ORA 00920在触发Oracle内部的“OR”的情况下

时间:2017-09-06 20:25:46

标签: sql oracle plsql

语法错误似乎在WHEN INSERTING OR UPDATING中(更具体地说它强调了OR),我不明白为什么它在CASE条件下不起作用但它在IF中起作用条件。

它是BEFORE DELETE OR INSERT OR UPDATE触发器

问题的代码部分:

SELECT 
    field 
INTO 
    my_var
FROM 
    my_table
WHERE 
    column1 = (CASE 
                        WHEN INSERTING OR UPDATING THEN 
                            :new.column2
                        ELSE --deleting
                            :old.column2
                        END);

解决方案是什么?

如果有人想要测试,那么以下是触发器的其余部分:https://pastebin.com/AJqGQyG8

编辑: 问题似乎是WHEN条件需要一个操作符,所以我尝试使用:

WHEN INSERTING = TRUE

但这只会导致另一个错误:

  

ORA-00904:“TRUE”:标识无效

2 个答案:

答案 0 :(得分:2)

我认为问题在于PL / SQL在触发器中知道这些布尔变量,但不幸的是Oracle的SQL不知道BOOLEAN。

一种解决方案可能是:

{{1}}

答案 1 :(得分:2)

正如Thorsten所解释的那样,insertingupdating以及deleting是谓词(BOOLEAN数据类型的表达式),它们仅存在于触发器的PL / SQL代码部分中。它们不能在SQL语句中存在(或以任何方式使用),因为Oracle SQL无法识别/实现BOOLEAN数据类型。

此外,:new.<whatever>:old.whatever也仅在触发器的PL / SQL部分可用;如果你有嵌入式SQL,那么像:new.<whatever>这样的东西被解释为绑定变量,不会有任何特殊之处,并且会提示你输入一个值(如果你使用&#34;高级&#34;前端程序)或者您只是会收到一个错误,告诉您并非所有变量都受到约束。

Thorsten已经展示了一种做你想做的事情的方法。如果你真的需要(想要?)使用case表达式,你可以这样做:

在触发器的v_value部分声明一个变量(如Thorsten答案中的DECLARE)。为其分配适当的数据类型。

然后在执行块中写下这样的东西,在SQL语句之前:

v_value := case when inserting or updating then :new.column2 else :old.column2 end;

然后在SQL语句中与v_value进行比较,同样在Thorsten的回答中。

或者,您可以在通常(PL / SQL)方式中将v_value块中的值分配给DECLARE块,就像您声明它一样。在任何情况下,必须在SQL语句之外分配值,而不是在其中。