【问题标题】:How to describe a reference cursor associated with dynamic SQL in Oracle?如何描述Oracle中与动态SQL关联的引用游标?
【发布时间】:2013-09-30 05:35:34
【问题描述】:

这是我的第一个(已编辑)stackoverflow 问题,请多多包涵。

在 Oracle 11g 中,我需要描述/询问从过程调用返回的引用游标的基础列在另一个数据库上通过 dblink,其中实际的 SQL 并不总是“显式”,但有时是动态生成的。

例如:

declare
    v_ref_cur sys_refcursor;
    v_cur_num number;
    v_col_count number;
    v_col_table dbms_sql.desc_tab3;
begin
    myProc@myDblink(v_ref_cur, 'myvalue');
    v_cur_num := dbms_sql.to_cursor_number(v_ref_cur);
    dbms_sql.describe_columns3(v_cur_num, v_col_count, v_col_table);
    ...
end

如果另一个数据库上的 myProc() 有一个“显式”SQL 语句,例如:

open cursor for select * from foo where bar = myParam;

光标转换和描述(仍然)工作得很好——我可以确定过程返回的列名、类型、长度等。

但是,如果其他数据库上的 myProc() 涉及动态 SQL,例如:

v_sql := 'select * from foo where bar = ''' || myParam || '''';
open cursor for v_sql;

我在尝试调用 dbms_sql.to_cursor_number() 时收到 ORA-01001 无效游标错误。

有没有办法转换/描述从远程过程调用的动态 SQL 派生的引用游标?如果是这样,怎么做?如果没有,为什么不呢?

感谢您的任何/所有帮助!

【问题讨论】:

    标签: oracle oracle11g cursor


    【解决方案1】:

    跨数据库链接使用 DBMS_SQL 会引发许多不同的错误,其中至少有一些是 Oracle 错误。这些问题可以通过将所有逻辑放在远程服务器上编译的函数中来避免。然后远程调用该函数。

    --Create and test a database link
    create database link myself connect to <schema> identified by "<password>"
        using '<connect string or service name>';
    select * from dual@myself;
    
    --myProc
    create procedure myProc(p_cursor in out sys_refcursor, p_value varchar2) is
    begin
        --open p_cursor for select * from dual where dummy = p_value;
        open p_cursor for 'select * from dual where dummy = '''||p_value||'''';
    end;
    /
    
    --Simple function that counts and displays the columns.  Expected value is 1.
    create or replace function count_columns return number is
        v_ref_cur sys_refcursor;
        v_cur_num number;
        v_col_count number;
        v_col_table dbms_sql.desc_tab3;
    begin
        --ORA-01001: invalid cursor
        --myProc@myself(v_ref_cur, 'myvalue');
        myProc(v_ref_cur, 'myvalue');
        --ORA-03113: end-of-file on communication channel
        --v_cur_num := dbms_sql.to_cursor_number@myself(v_ref_cur);
        v_cur_num := dbms_sql.to_cursor_number(v_ref_cur);
        --Compilation error: PLS-00306: 
        --    wrong number or types of arguments in call to 'DESCRIBE_COLUMNS3'
        --dbms_sql.describe_columns3@myself(v_cur_num, v_col_count, v_col_table);
        dbms_sql.describe_columns3(v_cur_num, v_col_count, v_col_table);
        return v_col_count;
    end;
    /
    
    begin
        dbms_output.put_line('Number of columns: '||count_columns@myself());
    end;
    /
    
    Number of columns: 1
    

    【讨论】:

    • 我忘了说明难度 - 调用的过程是远程的,通过 dblink 调用。对不起!
    • 好的,现在我可以重现问题了。但我现在没有时间调查它。我最初的想法是您可能需要将所有处理转移到远程服务器。
    猜你喜欢
    • 1970-01-01
    • 2016-12-19
    • 2017-10-31
    • 2018-06-21
    • 2014-09-11
    • 2014-11-20
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多