为啥会出现“ORA-00933:SQL 命令未正确结束”错误(立即执行)?
Posted
技术标签:
【中文标题】为啥会出现“ORA-00933:SQL 命令未正确结束”错误(立即执行)?【英文标题】:Why do I get "ORA-00933: SQL command not properly ended" error ( execute immediate )?为什么会出现“ORA-00933:SQL 命令未正确结束”错误(立即执行)? 【发布时间】:2021-11-30 16:02:09 【问题描述】:我创建了一个函数,它使用动态 sql:
create function check_ref_value
(
table_name varchar2,
code_value number,
code_name varchar2
) return number is
l_query varchar2(32000 char);
l_res number;
begin
l_query := '
select sign(count(1))
into :l_res
from '|| table_name ||'
where '|| code_name ||' = :code_value
';
execute immediate l_query
using in code_value, out l_res;
return l_res;
end;
但是当我尝试使用它时,我得到一个异常“ORA-00933:SQL 命令未正确结束” 这段代码有什么问题?
【问题讨论】:
【参考方案1】:您可以使用EXECUTE IMMEDIATE ... INTO ... USING ...
获取返回值,使用DBMS_ASSERT
在SQL 注入尝试的情况下引发错误:
create function check_ref_value
(
table_name varchar2,
code_value number,
code_name varchar2
) return number is
l_query varchar2(32000 char);
l_res number;
begin
l_query := 'select sign(count(1))'
|| ' from ' || DBMS_ASSERT.SIMPLE_SQL_NAME(table_name)
|| ' where ' || DBMS_ASSERT.SIMPLE_SQL_NAME(code_name)
|| ' = :code_value';
execute immediate l_query INTO l_res USING code_value;
return l_res;
end;
/
其中,对于样本数据:
CREATE TABLE abc (a, b, c) AS
SELECT 1, 42, 3.14159 FROM DUAL;
然后:
SELECT CHECK_REF_VALUE('abc', 42, 'b') AS chk FROM DUAL;
输出:
CHK 1
还有:
SELECT CHECK_REF_VALUE('abc', 42, '1 = 1 OR b') AS chk FROM DUAL;
引发异常:
ORA-44003: invalid SQL name ORA-06512: at "SYS.DBMS_ASSERT", line 160 ORA-06512: at "FIDDLE_UVOFONEFDEHGDQJELQJL.CHECK_REF_VALUE", line 10
至于你的问题:
这段代码有什么问题?
使用SELECT ... INTO
仅在PL/SQL 块中的SQL 语句中有效,并且当您通过EXECUTE IMMEDIATE
运行该语句时,它在SQL 范围内而不是PL/SQL 范围内执行。
您可以通过将动态代码包装在 BEGIN .. END
PL/SQL 匿名块中来修复它(并颠倒 USING
子句中绑定参数的顺序):
create function check_ref_value
(
table_name varchar2,
code_value number,
code_name varchar2
) return number is
l_query varchar2(32000 char);
l_res number;
begin
l_query := '
BEGIN
select sign(count(1))
into :l_res
from '|| DBMS_ASSERT.SIMPLE_SQL_NAME(table_name) ||'
where '|| DBMS_ASSERT.SIMPLE_SQL_NAME(code_name) ||' = :code_value;
END;
';
execute immediate l_query
using out l_res, in code_value;
return l_res;
end;
/
(但是,这比使用EXECUTE IMMEDIATE ... INTO ... USING ...
更复杂一些。)
db小提琴here
【讨论】:
以上是关于为啥会出现“ORA-00933:SQL 命令未正确结束”错误(立即执行)?的主要内容,如果未能解决你的问题,请参考以下文章
ORA-00933: SQL 命令未正确结束 00933. 00000 - “SQL 命令未正确结束