简单问题:
我有一个游标,它针对存储过程参数中提供的select语句运行,因此列数是未知的。
问题是如何打印列?
示例代码:
CREATE OR REPLACE Procedure MyExampleProcedure(P_QUERY VARCHAR2, P_dest VARCHAR2, P_file VARCHAR2)
AS
--Declaring types to use it for variables declarations
-----------------------------------------------
TYPE cursor_ref IS REF CURSOR;
TYPE typ_new_code IS TABLE OF VARCHAR2(50);
TYPE typ_new_desc IS TABLE OF VARCHAR2(500);
--Declaring variables based on previous types
-----------------------------------------------
c1 cursor_ref;
new_code typ_new_code;
new_desc typ_new_desc;
-----------------------------------------------
V_DEST_FILE utl_file.file_type;
BEGIN
V_DEST_FILE := utl_file.fopen(P_dest, P_file,'W');
OPEN c1 for P_QUERY;
FETCH C1 BULK COLLECT INTO new_code,new_desc;--This is the problematic area, not being able to iterate over the columns in the fetched row dynamically !
FOR I IN new_code.first .. new_code.last LOOP
utl_file.put(V_DEST_FILE, new_desc(i));
END LOOP;
utl_file.fclose(V_DEST_FILE);
EXCEPTION
WHEN NO_DATA_FOUND THEN
--Whatever
WHEN OTHERS THEN
--Whatever
END;
正如您所看到的,这仅适用于包含code
和desc
两列的select语句,无论名称是什么
答案 0 :(得分:2)
鉴于代码并且假设您使用的是11g,则无法在基础结果集中获取列名。如果您想这样做,您可能需要使用DBMS_SQL
包来打开游标,描述结果并获取数据。我想你也可以编写Java存储过程并使用JDBC API来描述查询。
假设您打算根据SQL语句生成某种文件,我强烈建议利用Tom Kyte's dump_csv procedure而不是尝试构建自己的文件。
答案 1 :(得分:1)
只为这项运动,可以做到 -
在打开游标之前添加:
dbms_output.put_line(dbms_xmlgen.getXMLType(P_QUERY)
.extract('ROWSET/ROW/*[1]').getrootelement());
dbms_output.put_line(dbms_xmlgen.getXMLType(P_QUERY)
.extract('ROWSET/ROW/*[2]').getrootelement());
(我使用了dbms_output.put_line但你也可以使用utl_file)
请注意,这意味着您只是为列名运行整个查询,因此这可能不是首选解决方案......