Oracle快速匯出平面檔案

壹頁書發表於2015-08-14
轉載自:
/>

  1. CREATE OR REPLACE DIRECTORY "MYDIR" AS '/home/oracle/';

  2. CREATE OR REPLACE TYPE dump_ot AS OBJECT
  3. (
  4.    file_name VARCHAR2 (128),
  5.    directory_name VARCHAR2 (128),
  6.    no_records NUMBER,
  7.    session_id NUMBER,
  8.    start_dttm TIMESTAMP WITH TIME ZONE,
  9.    end_dttm TIMESTAMP WITH TIME ZONE
  10. );

  11. CREATE OR REPLACE TYPE dump_ntt AS TABLE OF dump_ot;

  12. CREATE OR REPLACE FUNCTION DATA_UNLOAD (
  13.    p_source IN SYS_REFCURSOR,
  14.    p_filename IN VARCHAR2,
  15.    p_directory IN VARCHAR2,
  16.    p_unique_filename IN VARCHAR2 DEFAULT 'N',
  17.    p_create_log_file IN VARCHAR2 DEFAULT 'N')
  18.    RETURN dump_ntt
  19.    PIPELINED
  20.    PARALLEL_ENABLE(PARTITION p_source BY ANY)
  21. AS
  22.    /*
  23.    p_source SQL query you spool
  24.    p_filename targe file name
  25.    p_directory targe Oracle directory
  26.    p_unique_filename create unique file name? Y/N (appends unique SID to p_filename) - useful only for parallel unload
  27.    p_create_log_file create log file? Y/N (creates separate log file and logs every 1mm rows) - has very small performance hit on the spool
  28.    */

  29.    TYPE row_ntt IS TABLE OF VARCHAR2 (32767);

  30.    v_rows row_ntt;
  31.    v_file UTL_FILE.FILE_TYPE;
  32.    v_log_file UTL_FILE.FILE_TYPE;
  33.    v_buffer VARCHAR2 (32767);
  34.    v_sid VARCHAR (255);
  35.    v_name VARCHAR2 (255);
  36.    v_lines PLS_INTEGER := 0;
  37.    v_start_dttm TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP;
  38.    v_end_dttm TIMESTAMP WITH TIME ZONE;
  39.    v_create_log BOOLEAN := FALSE;

  40.    c_eol CONSTANT VARCHAR2 (1) := CHR (10);
  41.    c_eollen CONSTANT PLS_INTEGER := LENGTH (c_eol);
  42.    c_maxline CONSTANT PLS_INTEGER := 32767;
  43.    c_log_limit CONSTANT PLS_INTEGER := 1000000;
  44. BEGIN
  45.    v_sid := LPAD (SYS_CONTEXT ('USERENV', 'sid'), 10, '0');
  46.    v_name := p_filename;

  47.    IF TRIM (UPPER (p_create_log_file)) = 'Y'
  48.    THEN
  49.       v_create_log := TRUE;
  50.    END IF;

  51.    -- add SID (must be used for parallel spooling, single spooling or spooling across db-link creates alsway one file)
  52.    IF UPPER (p_unique_filename) = 'Y'
  53.    THEN
  54.       v_name := v_name || '_' || TO_CHAR (v_sid);
  55.    END IF;

  56.    v_file :=
  57.       UTL_FILE.FOPEN (p_directory,
  58.                       v_name,
  59.                       'w',
  60.                       c_maxline);

  61.    IF v_create_log
  62.    THEN
  63.       v_log_file :=
  64.          UTL_FILE.FOPEN (p_directory,
  65.                          v_name || '.LOG',
  66.                          'w',
  67.                          c_maxline);
  68.       UTL_FILE.PUT_LINE (
  69.          v_log_file,
  70.          TO_CHAR (v_start_dttm, 'DD-MON-YYYY HH24:MI:SS:FF3') || ' --> START');
  71.       UTL_FILE.FFLUSH (v_log_file);
  72.    END IF;

  73.    LOOP
  74.       FETCH p_source
  75.          BULK COLLECT INTO v_rows
  76.          LIMIT 10000;

  77.       FOR i IN 1 .. v_rows.COUNT
  78.       LOOP
  79.          IF LENGTHB (v_buffer) + c_eollen + LENGTHB (v_rows (i)) <= c_maxline
  80.          THEN
  81.             v_buffer := v_buffer || c_eol || v_rows (i);
  82.          ELSE
  83.             IF v_buffer IS NOT NULL
  84.             THEN
  85.                UTL_FILE.PUT_LINE (v_file, v_buffer);
  86.             END IF;

  87.             v_buffer := v_rows (i);
  88.          END IF;
  89.       END LOOP;

  90.       v_lines := v_lines + v_rows.COUNT;

  91.       IF v_create_log AND MOD (v_lines, c_log_limit) = 0
  92.       THEN
  93.          UTL_FILE.PUT_LINE (
  94.             v_log_file,
  95.                TO_CHAR (SYSTIMESTAMP, 'DD-MON-YYYY HH24:MI:SS:FF3')
  96.             || ' --> '
  97.             || v_lines);
  98.          UTL_FILE.FFLUSH (v_log_file);
  99.       END IF;

  100.       EXIT WHEN p_source%NOTFOUND;
  101.    END LOOP;

  102.    CLOSE p_source;

  103.    UTL_FILE.PUT_LINE (v_file, v_buffer);
  104.    UTL_FILE.FCLOSE (v_file);
  105.    v_end_dttm := SYSTIMESTAMP;

  106.    IF v_create_log
  107.    THEN
  108.       UTL_FILE.PUT_LINE (
  109.          v_log_file,
  110.             TO_CHAR (v_end_dttm, 'DD-MON-YYYY HH24:MI:SS:FF3')
  111.          || ' --> '
  112.          || v_lines);
  113.       UTL_FILE.PUT_LINE (
  114.          v_log_file,
  115.          TO_CHAR (v_end_dttm, 'DD-MON-YYYY HH24:MI:SS:FF3') || ' --> END');
  116.       UTL_FILE.FCLOSE (v_log_file);
  117.    END IF;

  118.    PIPE ROW (dump_ot (v_name,
  119.                       p_directory,
  120.                       v_lines,
  121.                       v_sid,
  122.                       v_start_dttm,
  123.                       v_end_dttm));
  124.    RETURN;
  125. END;
  126. /

  127. SELECT *
  128.   FROM TABLE (
  129.           DATA_UNLOAD (
  130.              CURSOR (
  131.                 SELECT /*+ parallel(u,4) */
  132.                       log_id
  133.                        || ','
  134.                        || typeid
  135.                        || ','
  136.                        || to_id
  137.                        || ','
  138.                        || to_msg
  139.                        || ','
  140.                        || userid
  141.                        || ','
  142.                        || nickname
  143.                        || ','
  144.                        || showing
  145.                        || ','
  146.                        || fromip
  147.                        || ','
  148.                        || TO_CHAR (createtime, 'yyyy-mm-dd HH24:mi:ss')
  149.                   FROM mvbox_space.user_visit u),
  150.              'SAMPLE_SPOOL.TXT',
  151.              'MYDIR',
  152.              'Y',
  153.              'N'));

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1771194/,如需轉載,請註明出處,否則將追究法律責任。

相關文章