0

简单的问题:

我有一个针对存储过程参数中提供的选择语句运行的游标,因此列数未知。

问题是如何打印列?

示例代码:

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;

如您所见,这仅适用于具有两列的 select 语句,code并且desc与名称无关

4

2 回答 2

2

鉴于该代码并假设您使用的是 11g,您无法获取基础结果集中的列名。如果您想这样做,您可能需要使用DBMS_SQL包来打开游标、描述结果并获取数据。我想您也可以编写一个 Java 存储过程并使用 JDBC API 来描述查询。

假设您的意图是基于 SQL 语句生成某种文件,我强烈建议利用Tom Kyte 的 dump_csv 过程,而不是尝试构建自己的文件。

于 2013-06-12T08:18:09.250 回答
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)

请注意,这意味着您仅针对列名运行整个查询,因此这可能不是首选的解决方案...

于 2013-06-12T08:33:15.257 回答