postgresql 从触发器中释放出来没有发生?

p3rjfoxz  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(1)|浏览(161)

我是PostgreSQL中触发器的新手。
在这个例子中,我有3个表table1table2table3

  • 触发器在table1上的新记录上触发。
  • trigger函数循环遍历table2中与table1中的新记录具有相同product_id的所有记录。
  • 它将前两个表中的一些混合值插入table3
  • 之后,将相同的INSERT查询插入到测试表中以进行测试。

问题是table3上的INSERT没有发生。测试表上的INSERT很好,记录的插入查询可以毫无问题地执行,所以我不知道为什么它不在触发器/函数中执行。

CREATE OR REPLACE FUNCTION my_trigger() RETURNS TRIGGER AS $my_trigger$
DECLARE r RECORD;
BEGIN
  FOR r IN SELECT t2.id_t2, t2.name_1, t2.name_2, t2.name_3 FROM table2 t2 WHERE t2.product_id=NEW.product_id 
  LOOP
    EXECUTE 'INSERT INTO table3 (id_t3, id_t1, name_1, name_2, name_3, bool_t2) VALUES (' || r.id_t2 || ',' || NEW.id_t1 || ', ''' || r.name_1 || ''',''' || r.name_2 || ''',''' || r.name_3 || ''', TRUE);';
    INSERT INTO test (field1, field2) VALUES(r.id_t2, 'INSERT INTO table3 (id_t3, id_t1, name_1, name_2, name_3, bool_t2) VALUES (' || r.id_t2 || ',' || NEW.id_t1 || ', ''' || r.name_1 || ''',''' || r.name_2 || ''',''' || r.name_3 || ''', TRUE);');
  END LOOP;
RETURN NEW;
END;
$my_trigger$ LANGUAGE plpgsql;

字符串
编辑:正如@Rachcha所问的,触发器本身是这样定义的:

CREATE TRIGGER my_trigger
  AFTER INSERT
  ON table1
  FOR EACH ROW
  EXECUTE PROCEDURE my_trigger();


编辑2:我也试过在没有EXECUTE的情况下插入,但结果是一样的:没有错误,但没有字段插入table3

neskvpey

neskvpey1#

功能更简单

AFTER触发器中使用RETURN NEW没有意义。请改用RETURN NULLThe manual:
对于在操作后触发的行级触发器,返回值被忽略,因此它们可以返回NULL
使用LOOP没有意义。使用简单的SQL语句代替。
EXECUTE中使用动态SQL没有意义。
这应该是可行的:

CREATE OR REPLACE FUNCTION my_trigger()
  RETURNS trigger
  LANGUAGE plpgsql AS
$func$
BEGIN
   INSERT INTO table3
         (   id_t3,     id_t1,    name_1, bool_t2)
   SELECT t2.id_t2, NEW.id_t1, t2.name_1, true
   FROM   table2 t2
   WHERE  t2.product_id = NEW.product_id;

   INSERT INTO test
         (  field1, field2)
   SELECT t2.id_t2, 'INSERT ...'
   FROM   table2 t2
   WHERE  t2.product_id = NEW.product_id;

   RETURN NULL;
END
$func$;

字符串
或者在CTE中从table2中提取SELECT,并在多个INSERT命令中使用:

...
   WITH t2 AS (
      SELECT t.id_t2, t.name_1
      FROM   table2 t
      WHERE  t.product_id = NEW.product_id
      )
   , ins_t3 AS (
      INSERT INTO table3
            (   id_t3,     id_t1,    name_1, bool_t2)
      SELECT t2.id_t2, NEW.id_t1, t2.name_1, true
      FROM   t2
      )
   INSERT INTO test
         (  field1, field2)
   SELECT t2.id_t2, 'INSERT ...'
   FROM   t2;
...


fiddle
老小提琴

如果它不起作用,问题就不在你的问题中。你有 * 任何 * 其他的触发器或规则定义在table1或表test上吗?
要进行调试,请将这一行添加到触发器函数中,以查看是否到达那里以及NEW中的值是什么

RAISE EXCEPTION 'Values in NEW: %', NEW::text;

相关问题