web-dev-qa-db-ja.com

SQLPLUSを使用してCSV形式のファイルにスプールする方法

いくつかのクエリをCSV出力形式に抽出したいです。残念ながら、私はそれを行うために任意の派手なSQLクライアントまたは任意の言語を使用することはできません。私はSQLPLUSを使わなければなりません。

どうすればいいのですか?

132

次のものも使用できますが、フィールド間にスペースが入ります。

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 
149
Gabe

このコマンドは、ディメンションテーブル(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を使用しません。

33

私は同様の問題を見ます...

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

私はそれがちょっとハードコアだと知っています、しかしそれは私のために働きます...

20
Karlos

新しいバージョンのクライアントツールでは、クエリ出力をフォーマットするための複数のオプションがあります。あとはクライアントツールに応じてファイルにスプールするか、ファイルとして出力を保存することです。ここにいくつかの方法があります。

  • 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 Version 3.2.20.1では、

enter image description here

これで、出力をファイルに保存することができました。

  • SQL Developerバージョン4.1

SQL Developerバージョン4.1の新機能として、sqlplusコマンドと同じように次のものを使用し、スクリプトとして実行します。クエリにヒントは必要ありません。

SET SQLFORMAT csv

これで、出力をファイルに保存することができました。

16
Lalit Kumar B

あなたが12.2を使っているなら、あなたは単に言うことができます

set markup csv on
14
BobC

私はこれが古いスレッドであることを知っています、しかし私は誰もが列見出しの下の下線を削除することができる下線オプションについて言及していないことに気づきました。

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;
9
Doc

それは原油です、しかし:

set pagesize 0 linesize 500 trimspool on feedback off echo off

select '"' || empno || '","' || ename || '","' || deptno || '"' as text
from emp

spool emp.csv
/
spool off
9
Tony Andrews

クエリを明示的にフォーマットして、以下の行に沿って何かを含む区切り文字列を生成できます。

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

そして必要に応じて出力オプションを設定します。オプションとして、SQLPlusのCOLSEP変数を使用すると、フィールドを連結した文字列を明示的に生成しなくても、区切りファイルを作成できます。ただし、埋め込みコンマ文字を含む可能性がある列では、文字列を引用符で囲む必要があります。

col nameを1つずつ編集するのではなく、sqlplus Promptで "set colsep"を使用することを推奨します。 sedを使って出力ファイルを編集します。

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

私はかつてdbms_sqlおよびdbms_outputを使用してcsv(実際にはssv)を作成する小さなSQL * Plusスクリプトを書いたことがあります。あなたはそれを見つけることができます 私のgithupリポジトリで

3

SQLを書くにはviかvimを使い、コントロールAと一緒にcolsepを使う(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ではないことはそれほど素晴らしいことではありませんか。

これはデータ内のコンマを処理するためです。私はそれらをセミコロンに変えます。

1
Charles Stepp

フィールドの値にカンマと引用符が含まれている可能性があるので、CSV出力ファイルが正しくないため、推奨される回答の一部は機能しません。フィールド内の引用符を置き換え、それを二重引用符で置き換えるには、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
1
Rob Heusdens

Sqlplusを使用してcsvファイルを作成する際に問題があります。列ヘッダーを1回だけ出力に含める必要があり、数千または数百万の行がある場合は、繰り返しを発生させないようにpagesizeを大きく設定することはできません。解決策は、pagesize = 50から始めてヘッダーを解析し、次にpagesize = 0を指定して再度selectを発行してデータを取得することです。下記の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
}
0
Larry R. Irwin

1994年にテーブルをCSVにダンプするためのこの純粋なSQLPlusスクリプトを作成しました。

スクリプトのコメントに記載されているように、Oracleの誰かが私のスクリプトをOracleサポートノートに入れましたが、帰属はありません。

https://github.com/jkstill/Oracle-script-lib/blob/master/sql/dump.sql

このスクリプトは、SQL * LOADERの制御ファイルとパラメーターファイルも作成します。

0
Jared Still