如何使用 SQLPLUS 假脱机到 CSV 格式的文件?
题
我想将一些查询提取为 CSV 输出格式。不幸的是,我无法使用任何奇特的 SQL 客户端或任何语言来做到这一点。我必须使用SQLPLUS。
我该怎么做?
解决方案
您也可以使用下面的地方,虽然它的字段之间引入空间。
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
...
这将是一个很大比打字出所有领域并具有逗号级联它们较繁琐。你可以用一个简单的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
我知道这有点硬核,但它对我有用......
使用较新版本的客户端工具,有多种选项可用于格式化查询输出。剩下的就是将其假脱机到文件或将输出保存为文件,具体取决于客户端工具。有以下几种方法:
- SQL*Plus
使用 SQL*Plus 命令,您可以格式化以获得所需的输出。使用 线轴 将输出假脱机到文件中。
例如,
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 之前版本
或者,您可以使用新的 /*csv*/
暗示 在 SQL开发人员.
/*csv*/
例如,在我的 SQL 开发人员版本 3.2.20.10:
现在您可以将输出保存到文件中。
- SQL 开发人员版本 4.1
SQL Developer 版本 4.1 中的新功能,使用以下命令,就像 sqlplus 命令并作为脚本运行。不需要查询中的提示。
SET SQLFORMAT csv
现在您可以将输出保存到文件中。
如果使用的是12.2,则可以简单地说
set markup csv on
我知道这是一个古老的线程,但是我注意到,没有人提到下划线选项,该选项可以删除列标题下的下划线
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;
这是粗的,但:
set pagesize 0 linesize 500 trimspool on feedback off echo off
select '"' || empno || '","' || ename || '","' || deptno || '"' as text
from emp
spool emp.csv
/
spool off
您可以明确地格式化查询产生分隔字符串沿着线的东西:
select '"'||foo||'","'||bar||'"'
from tab
和设置输出适当的选项。作为一个选项,在对的SQLPlus变量COLSEP会让你产生分隔的文件,而无需显式地产生与串联在一起的字段的字符串。然而,你将不得不把字串,行情就可能包含嵌入的逗号字符的任意列。
喜欢使用由一个“设定COLSEP”在sqlplus提示,而不是编辑栏名之一。用sed编辑的输出文件。
set colsep '","' -- separate columns with a comma
sed 's/^/"/;s/$/"/;s/\s *"/"/g;s/"\s */"/g' $outfile > $outfile.csv
我曾经写了一个小SQL * Plus脚本使用dbms_sql
和dbms_output
创建CSV(实际上是一个SSV)。你可以找到它 href="https://github.com/ReneNyffenegger/oracle_scriptlets/blob/master/sqlpath/to_csv.sql" rel="nofollow">。
使用vi或VIM写SQL中,使用COLSEP与控制-A(在vi和vim先于CTRL-A与CTRL-V)。一定要设置的LINESIZE和PAGESIZE的东西理性和打开trimspool和trimout。
阀芯它关闭到一个文件。 然后...
sed -e 's/,/;/g' -e 's/ *{ctrl-a} */,/g' {spooled file} > output.csv
这SED东西可以变成一个脚本。该“*”前后CTRL-A挤出所有的无用空间。是不是很大,他们不屑于实现从sqlplus的HTML输出,但不是本地CSV ?????
我做这种方式,因为它处理数据的逗号。我把它们以分号。
您应该知道,字段的值可以包含逗号和引号字符,所以一些建议的答案是行不通的,因为CSV输出文件是不正确。 要替换字段中的引号字符,并用双引号字符代替它,可以使用替换功能,Oracle提供,以改变一个单引号到双引号。
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
有是用sqlplus创建的CSV文件的问题。如果你想列标题只输出一次,有行的数千或数百万,你可以不设置页面大小不够得到重复大。 解决的办法是先从页面大小= 50,解析出的头,然后用页面大小= 0再次发出选择来获取数据。下面请参阅bash脚本:
#!/bin/bash
FOLDER="csvdata_mydb"
CONN="192.168.100.11:1521/mydb0023.world"
CNT=0376
ORD="0376"
TABLE="MY_ATTACHMENTS"
sqlplus -L logn/pswd@//${CONN}<<EOF >/dev/null
set pagesize 50;
set verify off;
set feedback off;
set long 99999;
set linesize 32767;
set trimspool on;
col object_ddl format A32000;
set colsep ,;
set underline off;
set headsep off;
spool ${ORD}${TABLE}.tmp;
select * from tblspc.${TABLE} where rownum < 2;
EOF
LINES=`wc -l ${ORD}${TABLE}.tmp | cut -f1 -d" "`
[ ${LINES} -le 3 ] && {
echo "No Data Found in ${TABLE}."
}
[ ${LINES} -gt 3 ] && {
cat ${ORD}${TABLE}.tmp | sed -e 's/ * / /g' -e 's/^ //' -e 's/ ,/,/g' -e 's/, /,/g' | tail -n +3 | head -n 1 > ./${ORD}${TABLE}.headers
}
sqlplus -L logn/pswd@//${CONN}<<EOF >/dev/null
set pagesize 0;
set verify off;
set feedback off;
set long 99999;
set linesize 32767;
set trimspool on;
col object_ddl format A32000;
set colsep ,;
set underline off;
set headsep off;
spool ${ORD}${TABLE}.tmp;
select * from tblspc.${TABLE};
EOF
LINES=`wc -l ${ORD}${TABLE}.tmp | cut -f1 -d" "`
[ ${LINES} -le 3 ] && {
echo "No Data Found in ${TABLE}."
}
[ ${LINES} -gt 3 ] && {
cat ${ORD}${TABLE}.headers > ${FOLDER}/${ORD}${TABLE}.csv
cat ${ORD}${TABLE}.tmp | sed -e 's/ * / /g' -e 's/^ //' -e 's/ ,/,/g' -e 's/, /,/g' | tail -n +2 | head -n -1 >> ${FOLDER}/${ORD}${TABLE}.csv
}
我写这纯粹的SQLPlus脚本来转储表以CSV在1994年
作为脚本评论中指出,有人在甲骨文把我的脚本在Oracle Support说明,但没有归属。
https://github.com/jkstill /oracle-script-lib/blob/master/sql/dump.sql
在脚本也还建立一个控制文件和用于SQL参数文件* LOADER
您可以使用CSV提示。请参见下面的示例:
select /*csv*/ table_name, tablespace_name
from all_tables
where owner = 'SYS'
and tablespace_name is not null;