我是 PostgreSQL 触发器的新手。
在这个例子中我有 3 个表
table1
、table2
和 table3
。
table1
上的新记录上触发。table2
中与 product_id
中的新记录具有相同 table1
的所有记录。table3
中。INSERT
查询插入到测试表中以进行测试。问题是
INSERT
上的 table3
没有发生。测试表上的INSERT
很好,记录的插入查询可以毫无问题地执行,所以我不知道为什么它不在触发器/函数内执行。
创建或替换函数 my_trigger() 返回触发器为 $my_trigger$ 声明 r 记录; 开始 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 环形 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);') ; 结束循环; 返回新的; 结尾; $my_trigger$ 语言 plpgsql;
编辑: 正如 @Rachcha 所问,触发器本身是这样定义的:
CREATE TRIGGER my_trigger
AFTER INSERT
ON table1
FOR EACH ROW
EXECUTE PROCEDURE my_trigger();
编辑2:我也尝试过在没有
EXECUTE
的情况下插入,但结果是相同的:没有错误,但没有字段插入table3
。
在
RETURN NEW
触发器中使用 AFTER
是没有意义的。请改用 RETURN NULL
。 说明书:
对于在某个事件之后触发的行级触发器,返回值将被忽略。 操作,因此他们可以返回
。NULL
使用
LOOP
没有意义。请改用简单的 SQL 语句。EXECUTE
毫无意义。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$;
或
SELECT
中的 table2
在 CTE 中使用一次,并在多个 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;
...
如果不起作用,则问题不在您的问题中。您是否在 table1
或表
test
上定义了任何其他触发器或规则?
要进行调试,请将此行添加到触发器函数中,看看您是否到达那里以及
NEW
中有哪些值
RAISE EXCEPTION 'Values in NEW: %', NEW::text;