如何使用SQLPLUScaching到CSV格式的文件?

我想提取一些查询到CSV输出格式。 不幸的是,我不能使用任何奇特的SQL客户端或任何语言来做到这一点。 我必须使用SQLPLUS。

我该怎么做?

你也可以使用下面的内容,尽pipe它在字段之间引入了空格。

set colsep , -- separate columns with a comma set pagesize 0 -- No header rows set trimspool on -- remove trailing blanks set headsep off -- this may or may not be useful...depends on your headings. set linesize X -- X should be the sum of the column widths set numw X -- X should be the length you want for numbers (avoid scientific notation on IDs) spool myfile.csv select table_name, tablespace_name from all_tables where owner = 'SYS' and tablespace_name is not null; 

输出将如下所示:

  TABLE_PRIVILEGE_MAP ,SYSTEM SYSTEM_PRIVILEGE_MAP ,SYSTEM STMT_AUDIT_OPTION_MAP ,SYSTEM DUAL ,SYSTEM ... 

这比input所有的字段并用逗号连接起来要麻烦很多。 如果需要,您可以使用简单的sed脚本来删除出现在逗号前面的空格。

像这样的东西可能会工作…(我的sed技能是非常生锈的,所以这可能需要工作)

 sed 's/\s+,/,/' myfile.csv 

我使用这个命令来提取维度表(DW)的数据。 所以我使用下面的语法:

 set colsep '|' set echo off set feedback off set linesize 1000 set pagesize 0 set sqlprompt '' set trimspool on set headsep off spool output.dat select '|', <table>.*, '|' from <table> where <conditions> spool off 

和工作。 我不使用sed来格式化输出文件。

我看到一个类似的问题…

我需要从SQLPLUS缓冲CSV文件,但输出有250列。

我做了什么来避免恼人的SQLPLUS输出格式:

 set linesize 9999 set pagesize 50000 spool myfile.csv select x from ( select col1||';'||col2||';'||col3||';'||col4||';'||col5||';'||col6||';'||col7||';'||col8||';'||col9||';'||col10||';'||col11||';'||col12||';'||col13||';'||col14||';'||col15||';'||col16||';'||col17||';'||col18||';'||col19||';'||col20||';'||col21||';'||col22||';'||col23||';'||col24||';'||col25||';'||col26||';'||col27||';'||col28||';'||col29||';'||col30 as x from ( ... here is the "core" select ) ); spool off 

问题是你会失去列标题名称…

你可以添加这个:

 set heading off spool myfile.csv select col1_name||';'||col2_name||';'||col3_name||';'||col4_name||';'||col5_name||';'||col6_name||';'||col7_name||';'||col8_name||';'||col9_name||';'||col10_name||';'||col11_name||';'||col12_name||';'||col13_name||';'||col14_name||';'||col15_name||';'||col16_name||';'||col17_name||';'||col18_name||';'||col19_name||';'||col20_name||';'||col21_name||';'||col22_name||';'||col23_name||';'||col24_name||';'||col25_name||';'||col26_name||';'||col27_name||';'||col28_name||';'||col29_name||';'||col30_name from dual; select x from ( select col1||';'||col2||';'||col3||';'||col4||';'||col5||';'||col6||';'||col7||';'||col8||';'||col9||';'||col10||';'||col11||';'||col12||';'||col13||';'||col14||';'||col15||';'||col16||';'||col17||';'||col18||';'||col19||';'||col20||';'||col21||';'||col22||';'||col23||';'||col24||';'||col25||';'||col26||';'||col27||';'||col28||';'||col29||';'||col30 as x from ( ... here is the "core" select ) ); spool off 

我知道这是一个硬核,但它适用于我…

使用较新版本的客户端工具,有多种选项可以格式化查询输出。 剩下的就是将其caching到一个文件中,或者根据客户端工具将输出保存为一个文件。 这里有几个方法:

  • 在SQL * Plus

使用SQL * Plus命令可以格式化以获得所需的输出。 使用SPOOL将输出后台打印到一个文件。

例如,

 SQL> SET colsep , SQL> SET pagesize 20 SQL> SET trimspool ON SQL> SET linesize 200 SQL> SELECT * FROM scott.emp; EMPNO,ENAME ,JOB , MGR,HIREDATE , SAL, COMM, DEPTNO ----------,----------,---------,----------,---------,----------,----------,---------- 7369,SMITH ,CLERK , 7902,17-DEC-80, 800, , 20 7499,ALLEN ,SALESMAN , 7698,20-FEB-81, 1600, 300, 30 7521,WARD ,SALESMAN , 7698,22-FEB-81, 1250, 500, 30 7566,JONES ,MANAGER , 7839,02-APR-81, 2975, , 20 7654,MARTIN ,SALESMAN , 7698,28-SEP-81, 1250, 1400, 30 7698,BLAKE ,MANAGER , 7839,01-MAY-81, 2850, , 30 7782,CLARK ,MANAGER , 7839,09-JUN-81, 2450, , 10 7788,SCOTT ,ANALYST , 7566,09-DEC-82, 3000, , 20 7839,KING ,PRESIDENT, ,17-NOV-81, 5000, , 10 7844,TURNER ,SALESMAN , 7698,08-SEP-81, 1500, , 30 7876,ADAMS ,CLERK , 7788,12-JAN-83, 1100, , 20 7900,JAMES ,CLERK , 7698,03-DEC-81, 950, , 30 7902,FORD ,ANALYST , 7566,03-DEC-81, 3000, , 20 7934,MILLER ,CLERK , 7782,23-JAN-82, 1300, , 10 14 rows selected. SQL> 
  • SQL Developer版本前4.1

或者,您可以在SQL Developer中使用新的/*csv*/ 提示

 /*csv*/ 

例如,在我的SQL Developer版本3.2.20.10中

在这里输入图像描述

现在,您可以将输出保存到文件中。

  • SQL Developer版本4.1

SQL Developer版本4.1中的新增function,就像使用sqlplus命令一样使用以下脚本。 查询中不需要提示。

 SET SQLFORMAT csv 

现在,您可以将输出保存到文件中。

你可以明确的格式化查询来产生一个分隔符的string。

 select '"'||foo||'","'||bar||'"' from tab 

并根据需要设置输出选项。 作为选项,SQLPlus上的COLSEPvariables可让您生成分隔文件,而不必显式生成字段串联在一起的string。 但是,您必须在可能包含embedded逗号字符的任何列上加上引号。

这很粗糙,但是:

 set pagesize 0 linesize 500 trimspool on feedback off echo off select '"' || empno || '","' || ename || '","' || deptno || '"' as text from emp spool emp.csv / spool off 

我知道这是一个古老的线程,但是我注意到没有人提到下划线选项,它可以删除列标题下的下划线。

 set pagesize 50000--50k is the max as of 12c set linesize 10000 set trimspool on --remove trailing blankspaces set underline off --remove the dashes/underlines under the col headers set colsep ~ select * from DW_TMC_PROJECT_VW; 

更喜欢在sqlplus提示符中使用“set colsep”,而不是逐个编辑col名。 使用sed编辑输出文件。

 set colsep '","' -- separate columns with a comma sed 's/^/"/;s/$/"/;s/\s *"/"/g;s/"\s */"/g' $outfile > $outfile.csv 

我曾经写过一个使用dbms_sqldbms_output创build一个csv(实际上是一个ssv)的SQL * Plus脚本。 你可以在我的githup库find它。

如果你使用12.2,你可以简单地说

 set markup csv on 

使用vi或vim编写sql,使用colsep和control-A(在vi和vim之前用ctrl-v在ctrl-A之前)。 一定要将linesize和pagesize设置为合理值,并打开trimspool和trimout。

将它closures到一个文件。 然后…

 sed -e 's/,/;/g' -e 's/ *{ctrl-a} */,/g' {spooled file} > output.csv 

那东西可以变成剧本。 ctrl-A之前和之后的“*”挤出所有无用的空格。 是不是很好,他们困扰,以启用从sqlplus html输出,但不是本地csv ?????

我这样做,因为它处理数据中的逗号。 我把它们变成了分号。

您应该知道,字段的值可能包含逗号和引号字符,所以一些build议的答案将无法正常工作,因为CSV输出文件不正确。 要replace字段中的引号字符,并将其replace为双引号字符,可以使用oracle提供的REPLACE函数将单引号更改为双引号。

 set echo off set heading off set feedback off set linesize 1024 -- or some other value, big enough set pagesize 50000 set verify off set trimspool on spool output.csv select trim( '"' || replace(col1, '"', '""') || '","' || replace(col2, '"', '""') || '","' || replace(coln, '"', '""') || '"' ) -- etc. for all the columns from yourtable / spool off 

或者,如果您希望字段的单引号字符:

 set echo off set heading off set feedback off set linesize 1024 -- or some other value, big enough set pagesize 50000 set verify off set trimspool on spool output.csv select trim( '"' || replace(col1, '''', '''''') || '","' || replace(col2, '''', '''''') || '","' || replace(coln, '''', '''''') || '"' ) -- etc. for all the columns from yourtable / spool off 

你可以使用csv提示。 看下面的例子:

 select /*csv*/ table_name, tablespace_name from all_tables where owner = 'SYS' and tablespace_name is not null;