执行动态 PL/SQL 块以执行求和并返回值
Posted
技术标签:
【中文标题】执行动态 PL/SQL 块以执行求和并返回值【英文标题】:Executing a dynamic PL/SQL block to execute a sum and return a value 【发布时间】:2017-03-23 00:40:47 【问题描述】:我编写了以下 PL/SQL 来动态执行作为字符串提供给我的公式。公式的最终输出应该返回 19
,我希望它会返回到我的 o_
变量中。
代码实际上运行没有错误,但没有给我预期的结果。我是否正确使用了DBMS_SQL
包?
请注意,这个问题的一个复杂因素是我不知道输入字符串(或公式)中将包含多少绑定变量。因此,我不能使用EXECUTE IMMEDIATE
执行动态PL/SQL 的策略,因为EXECUTE IMMEDIATE
假设您提前知道需要绑定多少变量。
我是否以正确的方式解决问题?有更好的方法吗?
DECLARE
cur_ INTEGER;
r_ NUMBER;
str_ VARCHAR2(2000) := 'BEGIN :out := :x * 3 + :y; END;';
x_ NUMBER := 3;
y_ NUMBER := 10;
o_ NUMBER;
BEGIN
cur_ := Dbms_SQL.open_cursor;
Dbms_SQL.Parse (cur_, str_, Dbms_SQL.Native);
Dbms_SQL.Bind_Variable (cur_, ':out', o_);
Dbms_SQL.Bind_Variable (cur_, ':x', x_);
Dbms_SQL.Bind_Variable (cur_, ':y', y_);
r_ := Dbms_SQL.Execute (cur_);
Dbms_SQL.Close_Cursor (cur_);
Dbms_Output.Put_Line ('Your variables: ' || x_ || ', ' || y_ || ', and out: ' || o_ || ', and R: ' || r_);
END;
【问题讨论】:
你的字符串是固定字符串吗?如果不是,您可以使用类似于this question 的答案中的内容。 @Nitish 我真的不确定你指的是什么。我在该页面上找不到任何与我提出的问题相近的内容。 【参考方案1】:您错过了DBMS_SQL.VARIABLE_VALUE 电话。
DECLARE
cur_ INTEGER;
r_ NUMBER;
str_ VARCHAR2(2000) := 'BEGIN :out := :x * 3 + :y; END;';
x_ NUMBER := 3;
y_ NUMBER := 10;
o_ NUMBER;
BEGIN
cur_ := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE (cur_, str_, DBMS_SQL.NATIVE);
DBMS_SQL.BIND_VARIABLE (cur_, ':out', o_);
DBMS_SQL.BIND_VARIABLE (cur_, ':x', x_);
DBMS_SQL.BIND_VARIABLE (cur_, ':y', y_);
r_ := DBMS_SQL.EXECUTE (cur_);
DBMS_SQL.VARIABLE_VALUE(cur_, ':out', o_);
DBMS_SQL.CLOSE_CURSOR (cur_);
DBMS_OUTPUT.PUT_LINE ('Your variables: ' || x_ || ', ' || y_ || ', and out: ' || o_ || ', and R: ' || r_);
END;
Your variables: 3, 10, and out: 19, and R: 1
【讨论】:
【参考方案2】:尝试使用“从对偶中选择 [您的计算]”,获取结果行并获取列值。
declare
res number;
cur_ integer;
r_ number;
str_ varchar2(2000) := 'select :x * 3 + :y from dual';
x_ number := 3;
y_ number := 10;
o_ number;
begin
cur_ := dbms_sql.open_cursor;
dbms_sql.parse(cur_, str_, dbms_sql.native);
dbms_sql.bind_variable(cur_, ':x', x_);
dbms_sql.bind_variable(cur_, ':y', y_);
dbms_sql.define_column(cur_, 1, o_);
r_ := dbms_sql.execute(cur_);
res := dbms_sql.fetch_rows(cur_); -- Fetch only the first row, no loop required
dbms_sql.column_value(cur_, 1, o_);
dbms_sql.close_cursor(cur_);
dbms_output.put_line('Your variables: ' || x_ || ', ' || y_ || ', and out: ' || o_ || ', and R: ' || r_);
end;
【讨论】:
我认为你可以使用单个dbms_sql.execute()
和 dbms_sql.fetch_rows
而不是 dbms_sql.EXECUTE_AND_FETCH()
@Rene 睡觉前发了这个问题,一觉醒来也想到了这个解决办法(一定是在做梦代码)。它确实有效(当然,代价是必须修改用户的输入字符串)。但恐怕我不会将此解决方案标记为“已接受的答案”,因为 Wernfried 的解决方案形式更直接地回答了这个问题。但是 +1 是因为跳出框框思考。非常感谢您的想法。以上是关于执行动态 PL/SQL 块以执行求和并返回值的主要内容,如果未能解决你的问题,请参考以下文章
Oracle PL/SQL:如何使用可变数组作为输出参数执行过程?
是否可以从 jdbc 调用 pl/sql 函数并按名称注册返回值?