一部のクエリをCSV出力形式に抽出したい。残念ながら、私はそれをするためにどんな派手なSQLクライアントもどんな言語も使うことができません。SQLPLUSを使用する必要があります。
どうすればいいのですか?
一部のクエリを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
set pagesize 1000
には、0の代わりに使用します。私の以前のコメントでは、同じファイルにリダイレクトできません:cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv
。
grep
し、tr
このようにgrep -v -- ----- myfile.csv | tr -d [:blank:] > 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
私はそれがちょっとハードコアであることを知っています、しかしそれは私のために働きます...
||
サブクエリも必要ですか?、サブクエリには必要ないと思います。しかし、はい、それは一次選択に必要です。
select x
は何ですか?これはそれなしで動作するはずです。@davidb、一次内部サブクエリでは連結は必要ありませんが、すべての列にcol1、col2 ...などのエイリアスを付けることは正しいです。そこで必要です。
クライアントツールの新しいバージョンでは、クエリ出力をフォーマットするための複数のオプションがあります。残りは、クライアントツールに応じて、ファイルにスプールするか、出力をファイルとして保存することです。以下にいくつかの方法を示します。
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の新しいヒントを使用することもできます。/*csv*/
/*csv*/
たとえば、私のSQL Developerバージョン3.2.20.10では:
これで、出力をファイルに保存できます。
SQL Developerバージョン4.1の新機能で、sqlplusコマンドと同じように以下を使用し、スクリプトとして実行します。クエリのヒントは必要ありません。
SET SQLFORMAT csv
これで、出力をファイルに保存できます。
私はこれが古いスレッドであることを知っていますが、列見出しの下にある下線を削除できる下線オプションについては誰も言及していません。
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変数を使用すると、フィールドを連結して明示的に文字列を生成する必要なく、区切りファイルを作成できます。ただし、埋め込まれたコンマ文字を含む可能性のある列では、文字列を引用符で囲む必要があります。
私はかつて、csv(実際にはssv)を使用dbms_sql
しdbms_output
て作成する小さなSQL * Plusスクリプトを記述しました。あなたは私のgithupリポジトリでそれを見つけることができます。
フィールドの値にはカンマと引用符が含まれている可能性があるため、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
trim()
不要です。
SQLを書き込むにはviまたはvimを使用し、control-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ではないのは素晴らしいことではありませんか?????
これは、データ内のコンマを処理するためです。私はそれらをセミコロンに変えます。
sqlplusを使用してcsvファイルを作成する際に問題があります。出力に列ヘッダーが1回だけ必要で、行が数千または数百万ある場合、繰り返しを取得しないように十分な大きさのページサイズを設定することはできません。解決策は、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
}
私はこの純粋なSQLPlusスクリプトを作成して、1994年にテーブルをCSVにダンプしました。
スクリプトのコメントに記載されているように、Oracleの誰かが私のスクリプトをOracleサポートのメモに入れましたが、帰属はありませんでした。
https://github.com/jkstill/oracle-script-lib/blob/master/sql/dump.sql
スクリプトは、SQL * LOADERの制御ファイルとパラメータファイルも作成します