想做出来一个具有下列功能的PROCEDURE,遇到一个问题,希望大家能帮帮忙。
入力参数:表名
出力:CSV文件()
功能:入力表名执行procedure,将指定表的数据全部导出到一个csv文件中。
问题:执行动态游标的时候,将取出来的 RECORD存放到何种对象内?
代码:
CREATE OR REPLACE PROCEDURE WriteCSV (avTBL IN VARCHAR2)
AS
    vSTR        VARCHAR2(255);
    TYPE typeREF_CURSOR is REF CURSOR;
    curGET_DATE typeREF_CURSOR;
    recGET_DATE XXXXXXXX;
BEGIN    vSTR := 'SELECT * FROM ' || avTBL;
    OPEN curGET_DATE FOR vSTR;
    LOOP
        FETCH curGET_DATE INTO recGET_DATE;
        EXIT WHEN curGET_DATE%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('1');
    END LOOP;EXCEPTION WHEN OTHERS THEN
    RAISE;
END;
其中红字部分就是问题所在,这个地方需要一个 RECORD类型,怎么定义这个类型?或者有其他方案可以解决这个问题?
感谢感谢。

解决方案 »

  1.   

    从all_tab_columns中得到该表的所有字段
    并用逗号或分号连接,得到字符串组合到vSTR中(当然可以通过字段类型,决定如何连接)得到结果再用回车符连接最终得到的字符串写入文件基本只要两句sql 就可以解决了但如果字段类型如果特殊就很麻烦了
      

  2.   

    感谢 fosjos 通过你的提醒,我换成下面这种方法好用了。里面细节还需要修正一下,不过不存在什么难度了。
    CREATE OR REPLACE PROCEDURE WriteCSV (avTBL IN VARCHAR2)
    AS
        vHandle     UTL_FILE.FILE_TYPE;
        vDirname    VARCHAR2(250);
        vFilename   VARCHAR2(250);
        vOutput1     VARCHAR2(32767);
        vOutput     VARCHAR2(32767);
        vSTR1       VARCHAR2(255);
        vSTR2       VARCHAR2(255);    TYPE typeREF_CURSOR is REF CURSOR;
        TYPE typeRESULT IS RECORD (RESULT VARCHAR2(255));
        curGET_DATE   typeREF_CURSOR;
        curGET_COLUMN typeREF_CURSOR;
        recGET_DATE   typeRESULT;
        recGET_COLUMN typeRESULT;
    BEGIN
        vDirname := 'c:\hzy';   -- ディレクトリの絶対パス名を書く
        vFilename := 'test.csv';
        vHandle := UTL_FILE.FOPEN(vDirname ,vFilename,'w', 32767);    vSTR1 := 'SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = ''' || avTBL || '''';
        OPEN curGET_COLUMN FOR vSTR1;
        LOOP
            FETCH curGET_COLUMN INTO recGET_COLUMN;
            IF curGET_COLUMN%NOTFOUND THEN
                SELECT RTRIM(vOutput1,'||'',''||')
                INTO   vOutput1
                FROM   DUAL;
                
                SELECT RTRIM(vOutput,',')
                INTO   vOutput
                FROM   DUAL;
                vOutput := vOutput || chr(10);
                EXIT;
            END IF;
            vOutput1 := vOutput1 || recGET_COLUMN.RESULT || '||'',''||';
            vOutput  := vOutput || recGET_COLUMN.RESULT || ',';
        END LOOP;
        CLOSE curGET_COLUMN;
        vSTR2 := 'SELECT ' || vOutput1 ||' FROM ' || avTBL;
        OPEN curGET_DATE FOR vSTR2;
        LOOP
            FETCH curGET_DATE INTO recGET_DATE;
            EXIT WHEN curGET_DATE%NOTFOUND;
            vOutput := vOutput || recGET_DATE.RESULT || chr(10);
        END LOOP;
        CLOSE curGET_DATE;
        UTL_FILE.PUT_LINE(vHandle, vOutput);
        UTL_FILE.FCLOSE(vHandle);
    EXCEPTION WHEN OTHERS THEN
        CLOSE curGET_COLUMN;
        CLOSE curGET_DATE;
        UTL_FILE.FCLOSE_ALL;
        RAISE;
    END;