|
带列名输出的版本:
CREATE OR REPLACE PROCEDURE SQL_TO_CSV2
(
P_QUERY IN VARCHAR2, -- PLSQL文
P_DIR IN VARCHAR2, -- 导出的文件放置目录
P_FILENAME IN VARCHAR2 -- CSV名
)
IS
L_THECURSOR INTEGER DEFAULT DBMS_SQL.OPEN_CURSOR;
L_COLCNT NUMBER := 0;
L_SEPARATOR VARCHAR2(1) := ',';
L_DESCTBL DBMS_SQL.DESC_TAB;
P_MAX_LINESIZE NUMBER := 32000;
lv_sql VARCHAR2(32000);
LV_ROW VARCHAR2(32000);
LV_HEADER VARCHAR2(32000);
BEGIN
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT=''YYYYMMDD HH24:MI:SS''';
DBMS_SQL.PARSE( L_THECURSOR, P_QUERY, DBMS_SQL.NATIVE );
DBMS_SQL.DESCRIBE_COLUMNS( L_THECURSOR, L_COLCNT, L_DESCTBL );
DBMS_SQL.CLOSE_CURSOR(L_THECURSOR);
LV_HEADER := 'UTL_FILE.put_line(L_OUTPUT,';
FOR I IN 1 .. L_COLCNT LOOP
IF i>1 THEN
LV_ROW := LV_ROW||'||'''||L_SEPARATOR||'''||';
LV_HEADER := LV_HEADER ||'||'''||L_SEPARATOR||'''||';
END IF;
LV_ROW := LV_ROW||'r(i).'||L_DESCTBL(I).COL_NAME;
LV_HEADER := LV_HEADER||''''||L_DESCTBL(I).COL_NAME||'''';
END LOOP;
LV_HEADER := LV_HEADER||');';
lv_sql := '
DECLARE
L_OUTPUT UTL_FILE.FILE_TYPE;
L_ROW Varchar2(32000) := NULL;
CURSOR c IS '||P_QUERY||';
TYPE tp_rows IS TABLE OF c%ROWTYPE INDEX BY PLS_INTEGER;
r tp_rows;
BEGIN
L_OUTPUT := UTL_FILE.FOPEN('''||P_DIR||''', '''||P_FILENAME||'.tmp'', ''W'', '||P_MAX_LINESIZE||');
'||LV_HEADER||'
OPEN c;
LOOP
FETCH c BULK COLLECT INTO r LIMIT 2000;
FOR i IN 1..r.COUNT LOOP
L_ROW := '||LV_ROW||';
UTL_FILE.put_line(L_OUTPUT,L_ROW);
END LOOP;
EXIT WHEN c%NOTFOUND;
END LOOP;
CLOSE c;
UTL_FILE.FCLOSE( L_OUTPUT );
EXCEPTION
WHEN OTHERS THEN
UTL_FILE.FCLOSE( L_OUTPUT );
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
RAISE;
END;';
--DBMS_OUTPUT.PUT_LINE(lv_sql);
EXECUTE IMMEDIATE lv_sql;
-- UTL_FILE.fremove(P_DIR,to_char(sysdate,'yyyymmdd_')|| P_FILENAME||'.csv');
-- UTL_FILE.frename(P_DIR,P_FILENAME||'.tmp',P_DIR,to_char(sysdate,'yyyymmdd_')|| P_FILENAME||'.csv');
END;
/
|
|