执行动态PL / SQL块以执行求和并返回值

时间:2017-03-23 00:40:48

标签: oracle plsql dynamic-programming

我编写了以下PL / SQL来动态执行作为字符串给出的公式。公式的最终输出应返回19,我希望将其返回到o_变量。

代码实际上运行没有错误,但是没有给出我期望的结果。我是否正确使用DBMS_SQL包裹?

请注意,此问题的一个复杂因素是,我不知道输入字符串(或公式)中将包含多少绑定变量。因此,我不能使用执行动态PL / SQL的EXECUTE IMMEDIATE策略,因为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;

2 个答案:

答案 0 :(得分:3)

您错过了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

答案 1 :(得分:1)

尝试使用“从双重选择[您的计算]”,获取结果行并获取列值。

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;