执行动态 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 块以执行求和并返回值的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL学习笔记_03_存储函数与存储过程

Oracle PL/SQL:如何使用可变数组作为输出参数执行过程?

是否可以从 jdbc 调用 pl/sql 函数并按名称注册返回值?

忽略 PL/SQL 函数的返回值

Scala:如何按键分组并在 scala 中对值求和并以预期的返回类型返回列表

执行立即错误:PL/SQL:数字或值错误:字符到数字转换错误