为什么不在动态 SQL 中评估数学条件?
Why is a mathematical condition not being evaluated in dynamic SQL?
我已经尝试了以下检查条件并生成布尔结果的脚本。但是,如果我给出任何数学函数,它就不起作用,也不会显示值。
declare
l_sql varchar2(4000);
l_condition varchar2(4000);
ignore pls_integer;
l_cursor number;
l_names dbms_sql.varchar2_table;
begin
for i in 1..2 loop
if i = 1 then
l_condition := 'sysdate > to_date(''1/1/2007'',''mm/dd/yyyy'')';
else
l_condition := ':P1_ITEM = ' 'foo' '';
end if;
l_cursor := dbms_sql.open_cursor;
l_sql := 'begin wwv_flow.g_boolean := '||l_condition||'; end;';
l_names := wwv_flow_utilities.get_binds(l_sql);
dbms_sql.parse(l_cursor,l_sql,dbms_sql.NATIVE);
for i in 1 .. l_names.count loop
dbms_sql.bind_variable( l_cursor, l_names(i), v( substr(l_names(i),2) ), 32000 );
end loop;
ignore := dbms_sql.execute(l_cursor);
dbms_sql.close_cursor( l_cursor );
if wwv_flow.g_boolean then
dbms_output.put_line(l_condition||' is true.');
else
dbms_output.put_line(l_condition||' is false.');
end if;
end loop;
end;
我正在尝试使用 l_condition:= (5 > 3 AND 40 > 50) OR 10
进行评估。为什么它不起作用?
在评论中您曾说过您正在尝试 "solve the mathematical value (5 > 3 AND 40 > 50) OR 10",但这不是数学函数或有效的布尔逻辑。如果您确实进行了评估,则 5 > 3
为真而 40 > 50
为假,并且将它们加在一起到目前为止是有效的;但是你试图将结果与数字 10 进行 OR 运算,而不是另一个布尔表达式。所以你在做:
(TRUE AND FALSE) OR 10
如果将它插入代码中,它会抛出异常;您已将作业显示为:
l_condition:= (5 > 3 AND 40 > 50) OR 10
这会给你一个简单的 PLS-00382: expression is of wrong type
从块中的分配。如果你引用它,你会从动态 SQL 中得到同样的错误(删除不相关的绑定):
create package wwv_flow as
g_boolean boolean;
end wwv_flow;
/
declare
l_sql varchar2(4000);
l_condition varchar2(4000);
ignore pls_integer;
l_cursor number;
l_names dbms_sql.varchar2_table;
g_boolean boolean;
begin
for i in 1..2 loop
if i = 1 then
l_condition := 'sysdate > to_date(''1/1/2007'',''mm/dd/yyyy'')';
else
-- l_condition := ':P1_ITEM = ' 'foo' '';
l_condition:= '(5 > 3 AND 40 > 50) OR 10';
end if;
l_cursor := dbms_sql.open_cursor;
l_sql := 'begin wwv_flow.g_boolean := '||l_condition||'; end;';
-- l_names := wwv_flow_utilities.get_binds(l_sql);
dbms_sql.parse(l_cursor,l_sql,dbms_sql.NATIVE);
-- for i in 1 .. l_names.count loop
-- dbms_sql.bind_variable( l_cursor, l_names(i), v( substr(l_names(i),2) ), 32000 );
-- end loop;
ignore := dbms_sql.execute(l_cursor);
dbms_sql.close_cursor( l_cursor );
if wwv_flow.g_boolean then
dbms_output.put_line(l_condition||' is true.');
else
dbms_output.put_line(l_condition||' is false.');
end if;
end loop;
end;
/
ORA-06550: line 1, column 52:
PLS-00382: expression is of wrong type
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at "SYS.DBMS_SQL", line 1199
ORA-06512: at line 20
如果您删除“或 10”部分,则它会起作用:
declare
...
l_condition:= '(5 > 3 AND 40 > 50)';
...
end;
/
PL/SQL procedure successfully completed.
sysdate > to_date('1/1/2007','mm/dd/yyyy') is true.
(5 > 3 AND 40 > 50) is false.
所以问题不是您的代码不起作用,而是您的条件无效。如果你是 运行 this 来自另一个抑制异常的块(例如 when others
异常处理程序),或者你的客户端或调用它的任何东西没有报告异常,你需要找出原因并修复它。
我已经尝试了以下检查条件并生成布尔结果的脚本。但是,如果我给出任何数学函数,它就不起作用,也不会显示值。
declare
l_sql varchar2(4000);
l_condition varchar2(4000);
ignore pls_integer;
l_cursor number;
l_names dbms_sql.varchar2_table;
begin
for i in 1..2 loop
if i = 1 then
l_condition := 'sysdate > to_date(''1/1/2007'',''mm/dd/yyyy'')';
else
l_condition := ':P1_ITEM = ' 'foo' '';
end if;
l_cursor := dbms_sql.open_cursor;
l_sql := 'begin wwv_flow.g_boolean := '||l_condition||'; end;';
l_names := wwv_flow_utilities.get_binds(l_sql);
dbms_sql.parse(l_cursor,l_sql,dbms_sql.NATIVE);
for i in 1 .. l_names.count loop
dbms_sql.bind_variable( l_cursor, l_names(i), v( substr(l_names(i),2) ), 32000 );
end loop;
ignore := dbms_sql.execute(l_cursor);
dbms_sql.close_cursor( l_cursor );
if wwv_flow.g_boolean then
dbms_output.put_line(l_condition||' is true.');
else
dbms_output.put_line(l_condition||' is false.');
end if;
end loop;
end;
我正在尝试使用 l_condition:= (5 > 3 AND 40 > 50) OR 10
进行评估。为什么它不起作用?
在评论中您曾说过您正在尝试 "solve the mathematical value (5 > 3 AND 40 > 50) OR 10",但这不是数学函数或有效的布尔逻辑。如果您确实进行了评估,则 5 > 3
为真而 40 > 50
为假,并且将它们加在一起到目前为止是有效的;但是你试图将结果与数字 10 进行 OR 运算,而不是另一个布尔表达式。所以你在做:
(TRUE AND FALSE) OR 10
如果将它插入代码中,它会抛出异常;您已将作业显示为:
l_condition:= (5 > 3 AND 40 > 50) OR 10
这会给你一个简单的 PLS-00382: expression is of wrong type
从块中的分配。如果你引用它,你会从动态 SQL 中得到同样的错误(删除不相关的绑定):
create package wwv_flow as
g_boolean boolean;
end wwv_flow;
/
declare
l_sql varchar2(4000);
l_condition varchar2(4000);
ignore pls_integer;
l_cursor number;
l_names dbms_sql.varchar2_table;
g_boolean boolean;
begin
for i in 1..2 loop
if i = 1 then
l_condition := 'sysdate > to_date(''1/1/2007'',''mm/dd/yyyy'')';
else
-- l_condition := ':P1_ITEM = ' 'foo' '';
l_condition:= '(5 > 3 AND 40 > 50) OR 10';
end if;
l_cursor := dbms_sql.open_cursor;
l_sql := 'begin wwv_flow.g_boolean := '||l_condition||'; end;';
-- l_names := wwv_flow_utilities.get_binds(l_sql);
dbms_sql.parse(l_cursor,l_sql,dbms_sql.NATIVE);
-- for i in 1 .. l_names.count loop
-- dbms_sql.bind_variable( l_cursor, l_names(i), v( substr(l_names(i),2) ), 32000 );
-- end loop;
ignore := dbms_sql.execute(l_cursor);
dbms_sql.close_cursor( l_cursor );
if wwv_flow.g_boolean then
dbms_output.put_line(l_condition||' is true.');
else
dbms_output.put_line(l_condition||' is false.');
end if;
end loop;
end;
/
ORA-06550: line 1, column 52:
PLS-00382: expression is of wrong type
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at "SYS.DBMS_SQL", line 1199
ORA-06512: at line 20
如果您删除“或 10”部分,则它会起作用:
declare
...
l_condition:= '(5 > 3 AND 40 > 50)';
...
end;
/
PL/SQL procedure successfully completed.
sysdate > to_date('1/1/2007','mm/dd/yyyy') is true.
(5 > 3 AND 40 > 50) is false.
所以问题不是您的代码不起作用,而是您的条件无效。如果你是 运行 this 来自另一个抑制异常的块(例如 when others
异常处理程序),或者你的客户端或调用它的任何东西没有报告异常,你需要找出原因并修复它。