假设我有这样的触发器规范:
create table "t" (
"i" number(10)
);
create or replace trigger "trg"
before insert on "t"
referencing new as "n"
for each row
begin
null;
end;
如何引用 "n"
体内的标识符?这些都不起作用:"n"."i" := 2;
:"n"."i" := 2;
":n"."i" := 2;
:n."i" := 2;
所有这些尝试都会编译,但在尝试插入表时会产生此错误:ORA-04098: trigger 'TEST.trg' is invalid and failed re-validation
显然,我可以避免引用变量名,但是 1)这是关于从工具生成代码的,无论引用如何,它都必须正确地获取此语法,以及 2)我对正确的语法感到好奇。
绑定(bind)变量
在
CREATE TRIGGER
docs ,有一个引用(强调我的):In the trigger_body of a simple trigger or the tps_body of a compound trigger, a correlation name is a placeholder for a bind variable.
似乎绑定(bind)变量通常不支持引用,例如虽然这有效:
BEGIN
EXECUTE IMMEDIATE 'BEGIN dbms_output.put_line(:x); END;' USING 'a';
END;
这或任何类似的语法不会:BEGIN
EXECUTE IMMEDIATE 'BEGIN dbms_output.put_line(:"x"); END;' USING 'a';
END;
所以,这似乎是一致的,但我仍然对为什么我可以这样声明名称的规范感到好奇,但似乎无法引用它。数据库版本为 Oracle Database 18c Express Edition Release 18.0.0.0.0
最佳答案
根据文档,这些不是普通标识符,而是“相关名称”,预计为 new
, old
或 parent
:
Specifies correlation names, which refer to old, new, and parent values of the current row. Defaults: OLD, NEW, and PARENT.
可以使用替代名称:
If your trigger is associated with a table named OLD, NEW, or PARENT, then use this clause to specify different correlation names to avoid confusion between the table names and the correlation names.
但是你不能使用
"
在对相关名称的任何引用中。有趣的是,如果标识符都是大写的,你可以成功引用它:create or replace trigger "trg"
before insert on "t"
referencing new as "N"
for each row
begin
:N."i" := 2;
:n."i" := 2;
end;
https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/CREATE-TRIGGER-statement.html#GUID-AF9E33F1-64D1-4382-A6A4-EC33C36F237B__BABEBAAB
关于sql - 如何在 Oracle 触发器主体中使用带引号的 “referencing” 标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66008794/