【发布时间】:2014-02-06 15:04:16
【问题描述】:
我有一个带有更新前触发器的表,它可以通过更新同一行来触发自己,但更新语句的结果不是该触发器返回的最后一个值。我不明白它为什么以及如何工作。这个问题在例子上更容易理解:
BEGIN;
SET client_min_messages = 'notice';
CREATE TABLE public.test (
id INTEGER,
status INTEGER,
value numeric
);
CREATE SEQUENCE test_seq;
CREATE OR REPLACE FUNCTION public.test_tr() RETURNS trigger AS $body$
DECLARE
seq integer;
BEGIN
seq := nextval('test_seq');
RAISE NOTICE 'Started: %', seq;
IF new.status != old.status THEN
UPDATE test SET value = new.value WHERE id = new.id;
END IF;
RAISE NOTICE 'Finished: %, RETURNED NEW: %', seq, new;
RETURN new;
END
$body$ LANGUAGE 'plpgsql';
CREATE TRIGGER test_tr BEFORE UPDATE ON test FOR EACH ROW EXECUTE PROCEDURE test_tr();
INSERT INTO test (id, status, value) VALUES (1, 1, 1);
UPDATE test SET status = 2, value = 2 WHERE id = 1;
SELECT * FROM test;
ROLLBACK;
产生如下:
NOTICE: Started: 1
NOTICE: Started: 2
NOTICE: Finished: 2, RETURNED NEW: (1,1,2)
NOTICE: Finished: 1, RETURNED NEW: (1,2,2)
UPDATE 0
id | status | value
----+--------+-------
1 | 1 | 2
如您所见,最后返回的 new 是 (1,2,2) (status = 2, value = 2),但最后一个 SELECT 返回的行“status” = 1 和“value " = 2。为什么状态 = "1"?为什么不是“2”?
【问题讨论】:
-
您应该使用语句级触发器,而不是行级触发器。
标签: postgresql triggers