在创建触发器时使用“按新的旧方式重新命名”

时间:2018-07-11 12:41:47

标签: sql oracle plsql triggers

我在不同的表上发现了两个相似的触发器。

create or replace TRIGGER "GM_OWNER".CHG_TYPE_TRG
AFTER INSERT OR UPDATE OR DELETE
ON CHG_TYPE
FOR EACH ROW
BEGIN
    If Inserting Then
       INSERT INTO CHG_TYPE_H

create or replace TRIGGER invoice_trg
AFTER INSERT  OR  DELETE  OR UPDATE
ON invoice
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
    If Inserting Then
       INSERT INTO INVOICE_H

在与特定表相关的历史记录表中触发插入,更新或删除数据。 当我们已经在使用:old和:new来引用数据时,“按旧版本重命名新版本”有什么用?

2 个答案:

答案 0 :(得分:2)

:new和:old是用于解决旧记录和新记录的值的默认名称。

例如,您可以使用REFERENCING NEW AS A OLD AS B为它们命名。

答案 1 :(得分:1)

如果省略referencing子句,则使用默认值;如果您将其包含在内,则可以保留默认值,或者在更改其他名称为默认名称的同时更改其特定名称。

因此,如果您不想更改相关名称,则似乎没有包含该子句的任何要点-有些人可能会认为它是一件好事,因为它更为明确,但我个人认为只是重述默认值。

关于为什么要更改默认名称的原因,the documentation says

  

referencing_clause

     

指定相关性名称,这些名称引用当前行的旧值,新值和父值。 默认值OLDNEWPARENT

     

如果触发器与名为OLDNEWPARENT的表相关联,请使用此子句指定不同的相关性名称,以避免表名和相关性之间的混淆名称。

混乱部分似乎只是从触发器编写者的角度考虑,因为使用与触发器所在的表相同的名称或列似乎没有问题等等:

create table new (id number, new number);

create trigger trig
before insert on new
for each row
begin
  :new.new := 2;
end;
/

insert into new (id) values (1);

select * from new;

        ID        NEW
---------- ----------
         1          2

文档实际上是has an example,上面写着“为避免表名和相关名之间的冲突,...”,但似乎没有任何实际冲突。不过,使用其他名称似乎更清楚。

如果您的表中有一个“冲突的”名称,则我认为 less 仍然会混淆默认值,因为:old:new引用是即时可识别,其他任何事情都只会增加(少量)认知负担。

当然,由于OLDNEWPARENT是关键字(但不是保留字),因此您应该始终避免将它们用作标识符,但是您可以这样做。