从触发器INSERT没有发生?

时间:2013-03-19 16:17:38

标签: sql postgresql triggers plpgsql

我是PostgreSQL中触发器的新手 我在此示例中有3个表table1table2table3

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

问题是INSERT table3没有发生。测试表上的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

1 个答案:

答案 0 :(得分:1)

更简单的功能

  • RETURN NEW触发器中的AFTER没有任何意义。我改用RETURN NULL。 引用the manual here

      

    对于在a之后触发的行级触发器,将忽略返回值   操作,所以他们可以返回NULL。

  • 使用LOOP没有意义。请改用简单的SQL语句。

  • 使用动态SQL(EXECUTE)毫无意义。

CREATE OR REPLACE FUNCTION my_trigger()
  RETURNS TRIGGER AS
$my_trigger$
BEGIN

INSERT INTO table3 (id_t3, id_t1, name_1, name_2, name_3, bool_t2)
SELECT t2.id_t2, NEW.id_t1, t2.name_1, t2.name_2, t2.name_3, TRUE
FROM   table2 t2
WHERE  t2.product_id = NEW.product_id;

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

RETURN NULL;

END
$my_trigger$ LANGUAGE plpgsql;

这应该有效! -> SQLfiddle demo

调试

如果它不起作用,则问题不在您的问题中。您是否在table1或表test上定义了任何其他触发器或规则?

要进行调试,请将此行添加到触发器功能中,看看您是否到达那里以及NEW

中的值是什么
RAISE EXCEPTION 'Values in NEW: %', NEW::text;