您能帮我在 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 文件吗?的主要内容,如果未能解决你的问题,请参考以下文章