使用:new和:old引用SQL中的不同表

时间:2019-01-23 21:29:51

标签: sql database oracle triggers

为单项考试进行修订。一个问题指出:

编写一个SQL命令以在表Permission中创建触发器。的 触发器应在表文件的numberOfPermissions中添加一个 文件,每次在表中输入新的权限行之后 该文件名的权限。

here's a list of the tables provided

除了一条线(WHERE线)之外,我一切都变了。如何将:new值指定给其他表?它需要将新值读取为来自Permissions表的fileName列,但是我不确定如何做到这一点。我已经尝试过诸如:Permissions.new.fileName等方法,但是在“。”周围总是出现未指定的错误。点。

<body[\n\s\S]*?</body>

2 个答案:

答案 0 :(得分:4)

当我运行您的触发器创建代码in this db fiddle时,它会给我:

ORA-04082: NEW or OLD references not allowed in table level triggers

发生的事情是您在触发器的声明中省略了FOR EACH ROW选项。因此,Oracle认为您需要一个 table 级别触发器,该触发器每个 statement 执行一次(而 row 级别触发器则执行一次对于插入的每一行)。

由于一条语句可能导致插入多行(例如:INSERT INTO ... AS SELECT ...),因此Oracle不允许您访问表级触发器中的:NEW:OLD引用。

在触发器定义中添加FOR EACH ROW选项将使其成为行级触发器,允许访问:NEW:OLD引用。

CREATE TRIGGER newTrig
AFTER INSERT ON Permission
FOR EACH ROW
BEGIN
    UPDATE File 
    SET numberOfPermissions = numberOfPermissions+1 
    WHERE File.name = :new.fileName;
END;

PS:在UPDATE语句的末尾,您还缺少了分号。


不相关的PS:

> create table USER ( x number);
ORA-00903: invalid table name

> create table FILE ( x number);
ORA-00903: invalid table name

=>创建名称为保留字的表通常不是一个好主意,有时可能会导致棘手的错误。

答案 1 :(得分:0)

触发器知道应该更新哪些记录,因此可以使用“:OLD”指针。 尝试这样的事情:

    CREATE OR REPLACE TRIGGER newTrig
    AFTER INSERT ON Permission
    FOR EACH ROW
    BEGIN
        UPDATE File
        SET numberOfPermissions = numberOfPermissions+1 
        WHERE name = :old.fileName
    END;