Postgresql
觸發器無法訪問列循環
SSCCE:以下腳本:
$ cat test.sql CREATE TABLE public.foo ( loop INTEGER ); CREATE OR REPLACE FUNCTION public.foo_fun(loop INTEGER) RETURNS BOOLEAN AS $$ SELECT TRUE; $$ LANGUAGE SQL; CREATE OR REPLACE FUNCTION public.foo_tr_fun() RETURNS TRIGGER AS $$ DECLARE fRV BOOLEAN; BEGIN SELECT public.foo_fun(NEW.loop) INTO fRV; IF fRV THEN RETURN NEW; ELSE RAISE EXCEPTION 'bar'; END IF; END $$ LANGUAGE plpgsql; CREATE TRIGGER foo_tr AFTER INSERT OR UPDATE ON public.foo FOR EACH ROW EXECUTE PROCEDURE public.foo_tr_fun();
…我執行:
psql -v ON_ERROR_STOP=1 --quiet -X -U some-user -d some-db -f test.sql
foo
…當我嘗試在(從)中插入一行時psql
:$ psql -U some-user some-db psql (9.1.14) Type "help" for help. RegTAP=> SELECT * FROM public.foo; loop ------ (0 rows) RegTAP=> INSERT INTO public.foo(loop) VALUES(0); ERROR: record "new" has no field "loop" LINE 1: SELECT public.foo_fun(NEW.loop) ^ QUERY: SELECT public.foo_fun(NEW.loop) CONTEXT: PL/pgSQL function "foo_tr_fun" line 5 at SQL statement RegTAP=>
事實證明,關鍵字
loop
需要在 PL/pgSQL 中用雙引號引起來,否則解析器會感到困惑:SELECT public.foo_fun(NEW.**"loop"**) INTO fRV;
Postgres 9.3 中的情況沒有改變:
避免使用諸如
loop
標識符之類的典型關鍵字通常是個好主意。除了SQL 關鍵字之外,還有一些 plpgsql 關鍵字(例如用於過程元素或異常處理),但我不知道其他 plpgsql 關鍵字的完整列表。原始碼將是我最好的主意。我在 2007 年發現了關於 pgsql-hackers 的相關討論。看來這個問題還沒有完全解決。
在這裡也沒有看到 Postgres 9.4 的任何變化……