sql—如何使用触发器函数将行的值从一列移动到另一列?

jpfvwuh4  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(273)

我有两张table。一个主表和一种“备份”表。
主表如下所示:

id   |   name   |   a   |   b   
  int  |   text   |  int  |  int   
-------+----------+-------+-------
  1    |   Joe    |  100  |  10   
  2    |   Bill   |  200  |  40  
  3    |   Frank  |  200  |  20   
  4    |   Jack   |  100  |  10

备份表如下所示:

id   |   name1  |   a1  |   b1  |  name2 |  a2  | b2  |  name3 |  a3 | b3
  int  |   text   |  int  |  int  |  text  |  int | int |  text  | int | int 
-------+----------+-------+-------+--------+------+-----+--------+-----+----
  1    |   Joe    |  100  |  10   |        |      |     |        |     |
  2    |   Bill   |  200  |  40   |        |      |     |        |     |
  3    |   Frank  |  200  |  20   |        |      |     |        |     |
  4    |   Jack   |  100  |  10   |        |      |     |        |     |

我想在这里是如果我更新我的主表(或者 name 或者 a 或者 b 列),备份表中的值应移到“下一个”列。就像 name1name2 , a1a2 , b1b2 , name2name3 例如,如果我更新 JoeDon ,备份表如下所示:

UPDATE myschema.maintable
SET name = 'Don'
WHERE id = 1;
      id   |   name1  |   a1  |   b1  |  name2 |  a2  | b2  |  name3 |  a3 | b3
      int  |   text   |  int  |  int  |  text  |  int | int |  text  | int | int 
    -------+----------+-------+-------+--------+------+-----+--------+-----+----
      1    |   Don    |  100  |  10   |  Joe   | 100  | 10  |        |     |
      2    |   Bill   |  200  |  40   |        |      |     |        |     |
      3    |   Frank  |  200  |  20   |        |      |     |        |     |
      4    |   Jack   |  100  |  10   |        |      |     |        |     |

现在我知道这是一个非常糟糕的备份表的方法,但不幸的是它超出了我的控制,这就是我必须要做的。
我所尝试和期望的工作是:

CREATE OR REPLACE FUNCTION table_update_func()
RETURNS TRIGGER AS
$BODY$
BEGIN
UPDATE myschema.backuptable
SET 
name3 = name2,
a3 = a2,
b3 = b2,
name2 = name1,
b2 = a1,
b2 = b1,
name1 = name,
a1 = a,
b1 = b
FROM myschema.maintable
WHERE maintable.id = backuptable.id;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE

CREATE TRIGGER table_update_trig
BEFORE UPDATE 
ON myschema.maintable
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE table_update_func();

如果我更新了 maintale 它运行时不会出错,但它会移动每一行中的列,而不仅仅是我更新的列。我哪里出错了?我很确定我的状况 WHERE maintable.id = backup.id; 不好,但我不知道该怎么解决这个问题。

olmpazwi

olmpazwi1#

您正在将备份表与主表中的每一行连接起来,这就是为什么您总是更新备份表中的所有行。这里不需要from子句,因为在 new 记录。

CREATE OR REPLACE FUNCTION table_update_func()
RETURNS TRIGGER AS
$BODY$
BEGIN
UPDATE myschema.backuptable 
  SET name3 = name2,
      a3 = a2,
      b3 = b2,
      name2 = name1,
      b2 = a1,
      b2 = b1,
      name1 = new.name, -- reference the values of the new record here
      a1 = new.a,
      b1 = new.b
  WHERE backuptable.id = new.id; --<< no FROM clause necessary

  RETURN new; --<< IMPORTANT for a BEFORE UPDATE trigger!
END;
$BODY$
LANGUAGE plpgsql VOLATILE

相关问题