如果出现多个错误,则将 :new 中的列用于触发器

Posted

技术标签:

【中文标题】如果出现多个错误,则将 :new 中的列用于触发器【英文标题】:Using a column from :new into a trigger if, multiple errors 【发布时间】:2021-12-09 06:39:01 【问题描述】:

我正在尝试使用 :new 中的列(传入的新行)与另一个表中的日期进行比较,然后在满足条件时引发错误。

我尝试了两种解决方案:

CREATE OR REPLACE TRIGGER trigger_example
BEFORE INSERT ON STATION
FOR EACH ROW
DECLARE
    d1 DATE;
    d2 DATE;
BEGIN
    SELECT JOUR INTO d1 FROM ELECTION;
    SELECT DATEOUVERTURE INTO d2 FROM NEW;
    IF d1 = d2 THEN
        RAISE_APPLICATION_ERROR(-20001,'damn');
    end if;
end;

这是我从 NEW 中选择 DATEOUVERTURE 的地方,我收到此错误。

[2021-12-09 01:33:45] 6:39:PL/SQL: ORA-00942: table or view does not exist
[2021-12-09 01:33:45] 6:5:PL/SQL: SQL Statement ignored

但是表存在并且我有适当的读/写权限

第二种解决方案:

CREATE OR REPLACE TRIGGER trigger_example
BEFORE INSERT ON STATION
FOR EACH ROW
DECLARE
    d1 DATE;
    d2 DATE;
BEGIN
    SELECT JOUR INTO d1 FROM ELECTION;
    SELECT DATEOUVERTURE INTO d2 FROM :NEW;
    IF d1 = d2 THEN
        RAISE_APPLICATION_ERROR(-20001,'damn');
    end if;
end;

这是我从 :NEW 而不是 NEW 中选择的。但是我得到了这个错误。

[2021-12-09 01:36:56] 6:39:PLS-00049: bad bind variable 'NEW'
[2021-12-09 01:36:56] 6:43:PL/SQL: ORA-00903: invalid table name
[2021-12-09 01:36:56] 6:5:PL/SQL: SQL Statement ignored

有什么想法出错了吗?我找了好几个小时都找不到。

【问题讨论】:

每当查询SELECT * FROM user_tables WHERE table_name ='NEW' 时你会得到什么,它不是返回一行吗? 它不返回任何行。在这种情况下,我不想从名为 NEW 的表中获取信息。我正在尝试获取传入插入的特定列。 这里是ORA-00942返回的原因。 【参考方案1】:

你不能像这样使用:NEW。如果您替换以下示例应该可以工作

date_column_on_station_table 到您要在STATION 表中比较的列


CREATE OR REPLACE TRIGGER trigger_example
BEFORE INSERT ON STATION
FOR EACH ROW
DECLARE
    d1 DATE;
    d2 DATE;
BEGIN
    SELECT JOUR INTO d1 FROM ELECTION;
    IF d1 = :NEW.date_column_on_station_table THEN
        RAISE_APPLICATION_ERROR(-20001,'damn');
    end if;
end;

编辑: 如果DATEOUVERTURE 是要比较的列名,那么它应该是这样的:

CREATE OR REPLACE TRIGGER trigger_example
BEFORE INSERT ON STATION
FOR EACH ROW
DECLARE
    d1 DATE;
BEGIN
    SELECT JOUR INTO d1 FROM ELECTION;
    IF d1 = :NEW.DATEOUVERTURE THEN
        RAISE_APPLICATION_ERROR(-20001,'damn');
    end if;
end;

【讨论】:

当我尝试此解决方案时,我收到错误:无法解析列 'DATEOUVERTURE' '正在尝试在插入之前验证新的 DATEOUVERTURE 是否与 d1 相同) 嗯,它应该可以工作,您能否检查一下 DATEOUVERTURE 是否有错字 - 可能是缺少字母等? DATEOUVERTURE 拼写正确。 我在我的 oracle 数据库上对其进行了测试,它可以工作......我会在一段时间后删除答案,因为它不适合你 对我来说,您的第二个代码看起来不错。不过,d2 可以被删除,并且不知道select 是否会引发异常(就目前而言,该表仅包含一行 - 请注意 TOO_MANY_ROWS 甚至 NO_DATA_FOUND)。但这不是重点 - 我真的相信这段代码应该工作,关于 OP 发布的信息。 @Angry_sLmon,请编辑您发布的原始代码并显示表格的描述。

以上是关于如果出现多个错误,则将 :new 中的列用于触发器的主要内容,如果未能解决你的问题,请参考以下文章

用于以任何出现顺序匹配具有多个单词的列中的字符串的 Coredata 谓词

如果 Column_X 更新,PLSQL 触发器记录对审计表的更新

从另一个工作表的列中的工作表列中搜索每个值,如果找到,则将整行粘贴到输出中

Oracle PL / SQL触发器,在UPDATE之前/之后仅用于识别表中已修改的列

SP2-0552:未声明绑定变量“NEW”并且 END 错误报告 - 未知命令

[转]oracle触发器与:new,:old的使用