我对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:='begin'|| fakeproc()|| ';端;';
错误:PL / SQL:语句被忽略 行:654 文字:sqlstr:='begin'|| fakeproc()|| ';端;';
答案 0 :(得分:3)
首先创建一个过程来显示引用游标中的列名和值:
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
答案 1 :(得分: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
这假设该过程只有一个参数。答案是否需要适用于任何可能的参数组合?