NodeJS 更新和插入时的PgSQL触发函数

whhtz7ly  于 2023-08-04  发布在  Node.js
关注(0)|答案(2)|浏览(90)

我有两个表time_infocategory。我想在插入记录或更新time_info表的duration列时更新time_info表的temp_id
下面是模式

time_info

  • id
  • name-文本
  • 返回值NOT NULL
  • temp_id-整数
    类别
  • id
  • temp_id-整数
  • duration - smallint
    category表中有一些静态记录,这些记录的temp_id需要根据条件time_info.duration = category.duration填充到time_info表中。

示例类别
| 临时ID|持续时间| duration |
| --|--| ------------ |
| 一百二十三|三十| 30 |
| 二百三十四|六十| 60 |
| 三百四十五|九十| 90 |
因此,如果在time_info中添加记录,如
| 名称,名称|持续时间|临时ID| temp_id |
| --|--|--| ------------ |
| ABC|六十|||
然后触发器函数应该运行并更新行如下
| 名称,名称|持续时间|临时ID| temp_id |
| --|--|--| ------------ |
| ABC|六十|二百三十四| 234 |
现在,如果有人将time_info中的duration更改为90,则触发器函数应再次运行并将temp_id更新为345
我尝试了什么

CREATE FUNCTION update_time_info_temp_id() RETURNS trigger AS $update_time_info_temp_id$
    BEGIN
        UPDATE NEW  SET NEW.temp_id = subquery.temp_id
        FROM (SELECT * from category) AS subquery
        WHERE NEW.duration = subquery.duration; 

        RETURN NEW;
    END;
$update_time_info_temp_id$ LANGUAGE plpgsql;

CREATE TRIGGER update_time_info_temp_id AFTER INSERT OR UPDATE ON time_info
    FOR EACH ROW EXECUTE FUNCTION update_time_info_temp_id();

字符串
但似乎并不像预期的那样有效

u7up0aaq

u7up0aaq1#

看看这个这可能会解决问题。

CREATE OR REPLACE FUNCTION update_time_info_temp_id()
RETURNS TRIGGER AS $$
DECLARE
    value_to_update integer;
BEGIN
    SELECT temp_id INTO value_to_update
    FROM category
    WHERE duration = NEW.duration;
      
    UPDATE time_info
    SET temp_id = value_to_update
    WHERE id = NEW.id;

    RETURN NEW;
END;

CREATE TRIGGER update_time_info_temp_id_trigger
AFTER INSERT OR UPDATE OF duration ON time_info
FOR EACH ROW
EXECUTE FUNCTION update_time_info_temp_id();

字符串

rqqzpn5f

rqqzpn5f2#

你可能需要一个触发器。这可以让你避免更新,只是修改新的。您还可以在持续时间未更改时避免任何工作。

BEGIN;

CREATE TABLE category (id int PRIMARY KEY, temp_id int NOT NULL, duration int NOT NULL);

CREATE TABLE time_info (id int, name text, duration int NOT NULL, temp_id int NULL);

INSERT INTO category VALUES
    (1, 123, 30)
    , (2, 234, 60)
    , (3, 345, 90)
;

CREATE OR REPLACE FUNCTION tr_set_temp_id()
RETURNS TRIGGER
AS $$
BEGIN
    IF TG_OP = 'INSERT' OR NEW.duration IS DISTINCT FROM OLD.duration THEN
        NEW.temp_id := (SELECT temp_id FROM category WHERE duration = NEW.duration);
    END IF;
    RETURN NEW;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER trig_set_temp_id BEFORE INSERT OR UPDATE ON time_info
FOR EACH ROW EXECUTE PROCEDURE tr_set_temp_id();

INSERT INTO time_info VALUES (100, 'a', 30, NULL);
SELECT * FROM time_info;
UPDATE time_info SET duration = 60 WHERE id = 100;
SELECT * FROM time_info;

ROLLBACK;

字符串
请注意,您的模式(如定义的那样)有一些奇怪之处。category表的id看起来是多余的--你使用它的方式让我觉得duration才是真正的主键。在任何情况下,您肯定希望对它施加唯一约束。通常不会复制temp_id-如果需要,只需从time_info加入即可。
哦,你还没有说如果持续时间也不在类别表中会发生什么-你会想考虑这一点。

相关问题