【问题标题】:Get column names from procedure result从过程结果中获取列名
【发布时间】:2013-05-23 15:17:02
【问题描述】:

我对 db 没有经验,但我试图从存储过程的结果中获取列名。
代码必须是通用的,因为存储过程是未知的。 第一步是让它适用于没有输入参数的程序(只有 io_cursor)

到目前为止我的代码:

procedure fakeProc (
       io_cursor        in out t_ref_cursor
      )

以及我正在使用的代码:

PROCEDURE get_SQL_Fields (
       out_result    out varchar2)
as

/**/

v_cur         NUMBER        := NULL;
v_count       NUMBER        := NULL;

v_tab_desc    DBMS_SQL.DESC_TAB;
sqlstr        VARCHAR2(100);
BEGIN

v_cur := DBMS_SQL.OPEN_CURSOR;
    --Here i get errors
    sqlstr :='begin '|| fakeproc()||';end;';

    DBMS_SQL.PARSE(v_cur, sqlstr, DBMS_SQL.NATIVE);
    DBMS_SQL.DESCRIBE_COLUMNS(v_cur, v_count, v_tab_desc);

    FOR i IN 1..v_count LOOP
      out_result := out_result||v_tab_desc(i).COL_NAME||',';
    END LOOP;

  end if;
END get_SQL_Fields;

所以我现在的问题是构建这个 sqlstr ;
我得到的错误是:错误:PLS-00306:调用“FAKEPROC”时参数的数量或类型错误 线路:654 文本:sqlstr :='开始'|| fakeproc()||';end;';

错误:PL/SQL:语句被忽略 线路:654 文本:sqlstr :='开始'|| fakeproc()||';end;';

【问题讨论】:

  • 好吧,即使这可能不是唯一的问题,fakeProc 需要一个 t_ref_cursor parameter,而你调用它时不带参数...
  • 我知道。我试图在参数中放置一个 t_ref_cursor 但错误是绑定错误。
  • 可能duplicate
  • 可能是重复的,但我不明白。如何使用 :open v_cur for select * from table(cast(v_tab as tab_type)); ?
  • 您可以在尝试构建调用之前尝试使用 DBA_ARGUMENTS 来查找过程参数的名称和类型。分享和享受。

标签: oracle plsql


【解决方案1】:

首先创建一个过程来显示来自引用光标的列名和值:

CREATE OR REPLACE procedure printCur(in_cursor IN sys_refcursor) IS
begin

    FOR c IN (SELECT ROWNUM rn,
                    t2.COLUMN_VALUE.getrootelement () NAME,
                    EXTRACTVALUE (t2.COLUMN_VALUE, 'node()') VALUE
               FROM TABLE (XMLSEQUENCE (in_cursor)) t,
                    TABLE (XMLSEQUENCE (EXTRACT (COLUMN_VALUE, '/ROW/node()'))) t2
               order by 1)

   LOOP
      DBMS_OUTPUT.put_line (c.NAME || ': ' || c.VALUE);
   END LOOP;

exception
    when others then raise;
end;
/

现在像这样使用它:

declare

v_cur   sys_refcursor;

begin
    open v_cur for select 'ABC' as vchar_col1, sysdate as date_col2 from dual;

    printcur(v_cur);
exception
    when others then raise;

end;

输出:

VCHAR_COL1: ABC
DATE_COL2: 28-MAY-2013

【讨论】:

  • 感谢您的回复。我选择了 jonearles 的答案,因为它更适合我的需求和我的知识贫乏。感谢您的宝贵时间
【解决方案2】:

你已经接近了,你只是缺少 DBMS_SQL.TO_CURSOR_NUMBER 将游标转换为游标编号和动态 PL/SQL 绑定变量。

create or replace procedure fakeProc (io_cursor in out sys_refcursor) is
begin
    open io_cursor for 'select 1 column1, ''asdf'' column2 from dual';
end;
/

create or replace PROCEDURE get_SQL_Fields (
       out_result    out varchar2)
as
    v_cur         NUMBER        := NULL;
    v_count       NUMBER        := NULL;
    v_tab_desc    DBMS_SQL.DESC_TAB;
    v_cursor      SYS_REFCURSOR;
BEGIN
    execute immediate 'begin fakeProc(:v_cursor); end;' using in out v_cursor;
    v_cur := dbms_sql.to_cursor_number(v_cursor);
    DBMS_SQL.DESCRIBE_COLUMNS(v_cur, v_count, v_tab_desc);
    FOR i IN 1..v_count LOOP
        out_result := out_result||case when i = 1 then null else ',' end
            ||v_tab_desc(i).COL_NAME;
    END LOOP;
END get_SQL_Fields;
/

declare
    v_output varchar2(32767);
begin
    get_sql_fields(v_output);
    dbms_output.put_line(v_output);
end;
/

COLUMN1,COLUMN2

这假设该过程将只有一个参数。答案是否需要适用于任何可能的参数组合?

【讨论】:

  • 谢谢。这就是我需要的。我可以处理更多的论点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 2018-12-27
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 2020-03-14
相关资源
最近更新 更多