oracle DBMS_SQL.描述列导致ORA-29471:DBMS_SQL访问被拒绝

izkcnapc  于 2023-03-01  发布在  Oracle
关注(0)|答案(1)|浏览(192)

我不太熟悉PL/SQL。我正尝试在工作中运行以下过程。对DBMS_SQL.describe_columns的调用导致“ORA-29471:DBMS_SQL访问被拒绝”。如何解决此问题?我了解到DBMS_SQL包中的一些函数和过程在给定无效的游标ID时可能会引发此错误,但我在调用该包时在失败的行之前使用了该游标ID。因此,我不知道游标ID如何无效。

procedure ExecuteQuery (
      pio_report        IN OUT reports_dictionary_tab%ROWTYPE
      , pi_rpt_params   in out Report_Params2_obj
      , pi_vars         vchar100_tab_ty
      , pi_binds        vchar100_tab_ty
      , po_cursor       out gv_rc
      , po_columnDesc   out DBMS_SQL.desc_tab
      , pi_debug boolean default gv_debug
) is
    lv_rows integer;--Ignore return, not valid for SELECT or DDL, only DML.
    lv_columnCount integer; --Not sure if this is needed outside of this
    lv_cursorid integer;
begin

    lv_cursorid := DBMS_SQL.open_cursor;
    
    DBMS_SQL.parse( c => lv_cursorid, statement => pio_report.query, language_flag => dbms_sql.native);

    
    --set the bind variables...
    begin
        for b in 1..pi_vars.count loop
            DBMS_SQL.bind_variable ( c => lv_cursorid, name => pi_binds (b), value => pi_vars (b));
        end loop;

    exception
        when others then
            DebugOut( pi_table_name => 'Binds', pi_table => pi_binds , pi_debug => pi_debug);
            DebugOut( pi_table_name => 'Values', pi_table => pi_vars , pi_debug => pi_debug);
    end;

    --Ignore the row count coming back, it is undefined
    --for SELECT statements
    lv_rows := DBMS_SQL.EXECUTE (lv_cursorid);

    po_cursor := dbms_sql.to_refcursor(lv_cursorid);

    -- this line fails
    DBMS_SQL.describe_columns( c=> lv_cursorid, col_cnt => lv_columnCount , desc_t => po_columnDesc );

    for c in 1..po_columnDesc.count loop

        case po_columnDesc(c).col_type

            when gv_type_varchar then dbms_sql.define_column( c=> lv_cursorid, position => c, column => gv_datatype_varchar, column_size => gv_vchar2_col_size );
            when gv_type_char then dbms_sql.define_column( c=> lv_cursorid, position => c, column => gv_datatype_varchar, column_size => gv_vchar2_col_size );
            when gv_type_number then dbms_sql.define_column( c=> lv_cursorid, position => c, column => gv_datatype_number );
            when gv_type_date then dbms_sql.define_column( c=> lv_cursorid, position => c, column => gv_datatype_date );
            when gv_type_tstamp_tz then dbms_sql.define_column( c=> lv_cursorid, position => c, column => gv_datatype_tstamp_tz );
            when gv_type_clob then dbms_sql.define_column( c=> lv_cursorid, position => c, column => gv_datatype_clob );
            else DebugOut ( pi_text => 'Unknown Column type '||po_columnDesc(c).col_type||' for "'||po_columnDesc(c).col_name||'"' , pi_debug => pi_debug);
        end case;

    end loop; --End Column Definition Loop

end;
lawou6xi

lawou6xi1#

来自文档:
一旦将cursor_number转换为REF CURSOR,任何DBMS_SQL操作都无法再访问cursor_number。
如果你移动这条线,它就会运行

po_cursor := dbms_sql.to_refcursor(lv_cursorid);

直到手术结束。我不太确定你想达到什么目的...

相关问题