【问题标题】:Can you help me write a procedure in Oracle to spool data from a table to a CSV file?您能帮我在 Oracle 中编写一个程序来将数据从表中转存到 CSV 文件吗?
【发布时间】:2009-06-22 17:09:05
【问题描述】:

我正在编写一个过程来创建一个包含 Oracle 表中数据的 CSV 文件。我使用了"spool filename;",但出现了错误。我可以在 PL/SQL 中使用spool 吗?

【问题讨论】:

    标签: oracle plsql oracle10g


    【解决方案1】:

    我认为有更好的方法可以在 Oracle 10g/11g 上实现这一点,但这在 Oracle 9i 或更高版本上应该可以正常工作:

    CREATE OR REPLACE PROCEDURE prc_file_mult_column_generate(
    p_file_dir         VARCHAR2, -- mandatory (Oracle directory name)
    p_file_name     VARCHAR2, -- mandatory
    p_sql_query        VARCHAR2, -- Multiple column SQL SELECT statement that needs to be executed and processed
    p_delimiter     CHAR      -- column delimiter
    )
    AS
    
    l_cursor_handle  INTEGER;
    l_dummy              NUMBER;
    l_col_cnt          INTEGER;
    l_rec_tab            DBMS_SQL.DESC_TAB;
    l_current_col      NUMBER(16);
    l_current_line   VARCHAR2(2047);
    l_column_value   VARCHAR2(300);
    
    l_file_handle      UTL_FILE.FILE_TYPE;
    l_print_text       VARCHAR2(100);
    l_record_count   NUMBER(16) := 0;
    
    BEGIN
    
       /* Open file for append*/
       l_file_handle := UTL_FILE.FOPEN(p_file_dir, p_file_name, 'a', 2047); --Append Mode, 2047 chars per line max, possibly increasable
    
       l_cursor_handle := DBMS_SQL.OPEN_CURSOR;
       DBMS_SQL.PARSE(l_cursor_handle, p_sql_query, DBMS_SQL.native);
       l_dummy := DBMS_SQL.EXECUTE(l_cursor_handle);
    
       /* Output column names and define them for latter retrieval of data */
       DBMS_SQL.DESCRIBE_COLUMNS(l_cursor_handle, l_col_cnt, l_rec_tab); -- get column names
    
       /* Append to file column headers */
       l_current_col := l_rec_tab.FIRST;
       IF (l_current_col IS NOT NULL) THEN
          LOOP
             DBMS_SQL.DEFINE_COLUMN(l_cursor_handle, l_current_col, l_column_value, 300);
             l_print_text := l_rec_tab(l_current_col).col_name || p_delimiter;
             UTL_FILE.PUT (l_file_handle, l_print_text);
             l_current_col := l_rec_tab.NEXT(l_current_col);
             EXIT WHEN (l_current_col IS NULL);
          END LOOP;
       END IF;
       UTL_FILE.PUT_LINE (l_file_handle,' ');
    
       /* Append data for each row */
       LOOP
          EXIT WHEN DBMS_SQL.FETCH_ROWS(l_cursor_handle) = 0; -- no more rows to be fetched
    
          l_current_line := '';
          /* Append data for each column */
          FOR l_current_col IN 1..l_col_cnt LOOP
             DBMS_SQL.COLUMN_VALUE (l_cursor_handle, l_current_col, l_column_value);
             l_print_text := l_column_value || p_delimiter;
    
             l_current_line := l_current_line || l_column_value || p_delimiter;
          END LOOP;
          l_record_count := l_record_count + 1;
          UTL_FILE.PUT_LINE (l_file_handle, l_current_line);
       END LOOP;
    
       UTL_FILE.FCLOSE (l_file_handle);
       DBMS_SQL.CLOSE_CURSOR(l_cursor_handle);
    
    EXCEPTION
       WHEN OTHERS THEN
    
       -- Release resources
       IF DBMS_SQL.IS_OPEN(l_cursor_handle) THEN
          DBMS_SQL.CLOSE_CURSOR(l_cursor_handle);
       END IF;
    
       IF UTL_FILE.IS_OPEN (l_file_handle) THEN
          UTL_FILE.FCLOSE (l_file_handle);
       END IF;
    
       --RAISE ;
       DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.format_error_stack);
    
    END;
    /
    

    【讨论】:

      【解决方案2】:

      spool 是一个 sqlplus 命令。不能在pl/sql中使用。

      您似乎一直在尝试各种方法让 oracle 进行格式化和文件保存。为什么不让调用 proc 的程序为您完成这项工作?

      【讨论】:

        【解决方案3】:

        如果您只需要 cvs 文件中的数据,您可以这样做:

        使用如下查询创建一个 sql 文件:

        set feedback off verify off heading off pagesize 0
        select field1 || ',' || field2 ...  from table;
        quit;
        /
        

        然后像这样从终端调用 sqlplus:

        sqlplus -S user/password @file.sql> cvsfile.cvs
        

        【讨论】:

          【解决方案4】:

          不,SPOOL 是 SQL Plus 命令,因此您必须在 SQL Plus 中执行此操作:

          spool myfile.txt
          exec myproc
          spool off
          

          您可能还需要在开始该过程之前设置一些值,例如

          set pagesize 0 linesize 1000 trimspool on
          

          ...获取正确的格式。

          【讨论】:

            【解决方案5】:

            这里有几个链接可能对您有帮助:

            A PL/SQL Tutorial 和 SQL*Plus User Guide (11g)

            【讨论】:

              【解决方案6】:
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-07-14
              • 2022-11-10
              • 2022-08-06
              • 1970-01-01
              • 1970-01-01
              • 2020-05-22
              • 2017-06-16
              相关资源
              最近更新 更多