您能帮我在 Oracle 中编写一个程序来将数据从表中转存到 CSV 文件吗?

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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】:

创建一个 ascii 文件:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:459020243348 和 http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:68212348056 和 http://www.oracle-developer.net/display.php?id=425 。

【讨论】:

以上是关于您能帮我在 Oracle 中编写一个程序来将数据从表中转存到 CSV 文件吗?的主要内容,如果未能解决你的问题,请参考以下文章

谁能帮我写一个 R 数据框作为 SAS 数据集?

Oracle 表单选项卡详细信息

你能帮我解析这个 JSON 吗?

编写一个程序,读取5个整数并确定和打印其中的最大值,以下是我写的代码,错了,谁能帮我改改

谁能帮我翻译一下

你能帮我为matlab中ytop和ybot值的所有'ht'编写代码吗? [关闭]