Sql ORA 00920,如有;或;内触发甲骨文
插入或更新时,语法错误似乎出现在Sql ORA 00920,如有;或;内触发甲骨文,sql,oracle,plsql,Sql,Oracle,Plsql,插入或更新时,语法错误似乎出现在中(更具体地说,它在或下加下划线),我不明白为什么它在CASE条件下不起作用,但在IF条件下起作用 它是删除、插入或更新触发器之前的 问题的代码部分: SELECT field INTO my_var FROM my_table WHERE column1 = (CASE WHEN INSERTING OR UPDATING THEN
中(更具体地说,它在或
下加下划线),我不明白为什么它在CASE条件下不起作用,但在IF条件下起作用
它是删除、插入或更新触发器之前的
问题的代码部分:
SELECT
field
INTO
my_var
FROM
my_table
WHERE
column1 = (CASE
WHEN INSERTING OR UPDATING THEN
:new.column2
ELSE --deleting
:old.column2
END);
解决办法是什么
如果有人想测试,下面是触发器的其余部分:
编辑:
问题似乎是WHEN条件需要运算符,因此我尝试使用:
WHEN INSERTING = TRUE
但这只会导致另一个错误:
ORA-00904:“真”:识别无效
我认为问题在于PL/SQL知道触发器中的这些布尔变量,但不幸的是Oracle的SQL不知道布尔变量
一种解决方案可能是:
IF INSERTING OR UPDATING THEN
v_value := :new.column2;
ELSE
v_value := :old.column2;
END IF;
...
SELECT field INTO my_var FROM my_table WHERE column1 = v_value;
我认为问题在于PL/SQL知道触发器中的这些布尔变量,但不幸的是Oracle的SQL不知道布尔变量
一种解决方案可能是:
IF INSERTING OR UPDATING THEN
v_value := :new.column2;
ELSE
v_value := :old.column2;
END IF;
...
SELECT field INTO my_var FROM my_table WHERE column1 = v_value;
Thorsten已经解释过,插入
和更新
和删除
是谓词(布尔数据类型的表达式),它们只存在于触发器的PL/SQL代码部分。它们不能存在于SQL语句中(或以任何方式使用),因为Oracle SQL不能识别/实现布尔数据类型
此外,:new.
和:old.whatever
也仅在触发器的PL/SQL部分可用;如果您有嵌入式SQL,任何类似:new.
的内容都会被解释为绑定变量,在任何方面都不特殊,并且会提示您输入一个值(如果您使用“高级”前端程序),或者您只会得到一个错误,告诉您并非所有变量都已绑定
Thorsten已经展示了一种做你想做的事情的方法。如果您确实需要(想要?)使用case
表达式,可以执行以下操作:
在触发器的Declare
部分声明一个变量(如Thorsten答案中的v_value
)。为其指定适当的数据类型
然后在执行块中,在SQL语句之前编写如下内容:
v_value := case when inserting or updating then :new.column2 else :old.column2 end;
然后在SQL语句中,与v_值
进行比较,也与Thorsten的回答一样
或者,您可以在DECLARE
块中将值分配给v_value
,正如您所声明的那样,使用通常的(PL/SQL)方式。在任何情况下,都必须在SQL语句之外而不是在SQL语句中赋值。正如Thorsten已经解释的那样,插入
和更新
和删除
是谓词(布尔数据类型的表达式),它们只存在于触发器的PL/SQL代码部分。它们不能存在于SQL语句中(或以任何方式使用),因为Oracle SQL不能识别/实现布尔数据类型
此外,:new.
和:old.whatever
也仅在触发器的PL/SQL部分可用;如果您有嵌入式SQL,任何类似:new.
的内容都会被解释为绑定变量,在任何方面都不特殊,并且会提示您输入一个值(如果您使用“高级”前端程序),或者您只会得到一个错误,告诉您并非所有变量都已绑定
Thorsten已经展示了一种做你想做的事情的方法。如果您确实需要(想要?)使用case
表达式,可以执行以下操作:
在触发器的Declare
部分声明一个变量(如Thorsten答案中的v_value
)。为其指定适当的数据类型
然后在执行块中,在SQL语句之前编写如下内容:
v_value := case when inserting or updating then :new.column2 else :old.column2 end;
然后在SQL语句中,与v_值
进行比较,也与Thorsten的回答一样
或者,您可以在DECLARE
块中将值分配给v_value
,正如您所声明的那样,使用通常的(PL/SQL)方式。在任何情况下,都必须在SQL语句之外而不是在SQL语句中赋值。我认为您需要两个触发器,一个用于插入,一个用于更新。@TedFilippidis我想您的意思是一个用于插入/更新,另一个用于删除之前。当我有两个选择而不是大小写的IF/ELSE条件时,这是有效的,我只是想让代码更具可读性,但遇到了这个问题。是的,你是对的,如果你想简单一点,我会拆分触发器!为什么你不喜欢IF,如果它工作的话?如果它没有损坏,为什么要尝试修复,我总是说:D@TedFilippidis嗯,我只是觉得奇怪,CASE表达式不适用于OR,我只是想找出为什么^^^我认为需要两个触发器,一个用于插入,一个用于更新。@TedFilippidis我想你指的是一个用于插入/更新,另一个用于删除前的触发器当我有两个选择而不是大小写的IF/ELSE条件时,这是有效的,我只是想让代码更具可读性,但遇到了这个问题。是的,你是对的,如果你想简单一点,我会拆分触发器!为什么你不喜欢IF,如果它工作的话?如果它没有损坏,为什么要尝试修复,我总是说:D@TedFilippidis我只是觉得奇怪,CASE表达式不能与OR一起使用,我只是想找出原因^^