Postgresql
觸發功能不存在,但我很確定它存在
我有一個程序:
create or replace procedure pro_update_last_read(in input_sensor_id integer, in read_time timestamp) as $$ begin update sensor set last_read = read_time where sensor_id = input_sensor_id; end; $$ language plpgsql;
以及一個呼叫它的觸發器:
create trigger tri_last_read after insert or update of report_time on report execute procedure pro_update_last_read(sensor_id, report_time);
但是,在創建觸發器時,我收到錯誤消息:
[42883] ERROR: function pro_update_last_read() does not exist
為什麼會發生此錯誤?
您必須使用函式,而不是過程:
CREATE FUNCTION pro_update_last_read() RETURNS trigger ...
必須定義觸發器
FOR EACH ROW
,並且不能將列傳遞給觸發器函式。您訪問觸發器函式中的列的方式是通過
NEW
變數:NEW.sensor_id
和NEW.report_time
.
我將 Postgres函式的廣泛誤稱“儲存過程”歸咎於。這導致了使用這種語法創建觸發器的愚蠢行為:
CREATE TRIGGER ... FOR ... EXECUTE **PROCEDURE** function_name ...
不確定 SQL 標準的責任有多大,將“SQL 過程語句”稱為觸發操作。
在 Postgres 10 之前,潛在的混亂是有限的,因為只有functions。但是 Postgres 11 終於引入了真正的SQL過程。難怪有些人被誤導在那裡提供程序。
Postgres 11 中添加了更明智的替代語法:
CREATE TRIGGER ... FOR ... EXECUTE **FUNCTION** function_name ...
這不是向後兼容的。所以需要一些時間來接管。
如果您不必與 Postgres 10 或更早版本保持兼容,請使用新語法來提醒自己使用函式- 就像 Laurenz 指示的那樣。
有關的:
(最終實現儲存過程以及觸發器的新語法的也是 Peter Eisentraut。)