sql - 从触发器插入没有发生?

标签 sql postgresql triggers plpgsql

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

  • 触发器在 table1 上的新记录上触发。
  • 触发器函数遍历 table2 中与 table1 中的新记录具有相同 product_id 的所有记录。
  • 它将前 2 个表中的一些混合值插入到 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;

Edit: As @Rachcha asked, the trigger itself is defined this way:

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

编辑 2:我也尝试过不使用 EXECUTE 进行插入,但结果是一样的:没有错误,但没有字段插入到 table3 中。

最佳答案

更简单的功能

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

    The return value is ignored for row-level triggers fired after an operation, and so they can return 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;

关于sql - 从触发器插入没有发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15504827/

相关文章:

sql - 如何将记录作为参数传递给 PL/pgSQL 函数?

ruby-on-rails - 空字符串作为枚举类型列的默认值,而不是 Rails 中的 nil

sql - 如何更新 json 对象的键?

wpf - 尝试向按钮添加触发器以更改按钮的 Content 属性

创建触发器时 MySQL 语法错误

sql - 使用合并在 SQL 中合并两个表

sql - 在SQL Server 2008中加入Row_Number()

MYSQL 语句一起 OR 和 AND

SQL:如何检查外键是否真的改变了

java - 如何通过 MySQL 触发器执行外部 java 函数?