Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql ORA 00920,如有;或;内触发甲骨文_Sql_Oracle_Plsql - Fatal编程技术网

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一起使用,我只是想找出原因^^