如果您按照@Ychdziu 的建议打印出最终生成的语句,您会看到它最终为:
BEGIN IF :500.32 > 300 THEN :v_flag := 1; ELSE :v_flag := 0; END IF; END;
这不是你想要的。您要么需要提供要检查的值 (500.32) 作为绑定变量,如@Ychdziu 的回答中所示,要么将条件连接到语句中而不尝试创建另一个绑定变量:
DECLARE
v_flag NUMBER(2);
v_if_statement VARCHAR2(500);
v_sql_statement VARCHAR2(500);
v_criteria VARCHAR2(150);
v_condition VARCHAR2(30) := '%sales% > 300';
BEGIN
v_criteria := REPLACE(v_condition , '%sales%' , 500.32);
v_if_statement := 'IF '||v_criteria||' '||
'THEN :v_flag := 1;'||' '||
'ELSE :v_flag := 0;'||' '||
'END IF;';
v_sql_statement := 'BEGIN '||v_if_statement||' END;';
dbms_output.put_line('statament: '||v_sql_statement);
EXECUTE IMMEDIATE v_sql_statement USING OUT v_flag;
dbms_output.put_line('The output is : '||v_flag);
END;
/
现在生成的语句是
BEGIN IF 500.32 > 300 THEN :v_flag := 1; ELSE :v_flag := 0; END IF; END;
所以只有一个绑定变量。
但如果可以的话,通常最好绑定变量。在您的示例代码中,整个条件似乎是一个变量(我假设这只是一个练习,但它可以传入或来自表),因此您可以将两者结合起来并用绑定变量替换 %sales% 占位符改为参考:
DECLARE
v_flag NUMBER(2);
v_if_statement VARCHAR2(500);
v_sql_statement VARCHAR2(500);
v_criteria VARCHAR2(150);
v_condition VARCHAR2(30) := '%sales% > 300';
BEGIN
v_criteria := REPLACE(v_condition , '%sales%' , ':v_value');
v_if_statement := 'IF '||v_criteria||' '||
'THEN :v_flag := 1;'||' '||
'ELSE :v_flag := 0;'||' '||
'END IF;';
v_sql_statement := 'BEGIN '||v_if_statement||' END;';
dbms_output.put_line('statament: '||v_sql_statement);
EXECUTE IMMEDIATE v_sql_statement USING IN 500.32, OUT v_flag;
dbms_output.put_line('The output is : '||v_flag);
END;
/
不是生成的语句是:
BEGIN IF :v_value > 300 THEN :v_flag := 1; ELSE :v_flag := 0; END IF; END;
您可以通过USING 子句直接传递您想要检查的实际值500.32 - 可以像我在这里所做的那样作为文字,或者使用单独的数字变量。