Bagaimana cara spool ke file berformat CSV menggunakan SQLPLUS?
143
Saya ingin mengekstrak beberapa pertanyaan ke format output CSV. Sayangnya, saya tidak dapat menggunakan klien SQL mewah atau bahasa apa pun untuk melakukannya. Saya harus menggunakan SQLPLUS.
Tolong, tandai sebagai jawaban yang benar yang diberikan oleh @ Bob. Itu tidak ada perintah spool untuk mencetak file tetapi itu adalah solusi paling sederhana untuk mengekspor data dalam format csv.
rlar
Jawaban:
28
Jika Anda menggunakan 12.2, Anda bisa mengatakannya
Apakah ada yang tahu cara mematikan gema, "set gema mati" yang jelas tampaknya tidak berhasil dengan ini?
Quaternion
Dengan asumsi bahwa ini adalah karena Anda mengeksekusi skrip dan menulis ke file, Anda harus "menonaktifkan termout"
BobC
155
Anda juga bisa menggunakan yang berikut ini, meskipun itu memperkenalkan spasi antar bidang.
set colsep ,-- separate columns with a commaset pagesize 0-- No header rowsset trimspool on-- remove trailing blanksset headsep off-- this may or may not be useful...depends on your headings.set linesize X -- X should be the sum of the column widthsset numw X -- X should be the length you want for numbers (avoid scientific notation on IDs)
spool myfile.csvselect table_name, tablespace_name from all_tableswhere owner ='SYS'and tablespace_name isnotnull;
Ini akan jauh lebih membosankan daripada mengetik semua bidang dan menggabungkannya dengan koma. Anda bisa menindaklanjutinya dengan skrip sed sederhana untuk menghapus spasi putih yang muncul sebelum koma, jika Anda mau.
Sesuatu seperti ini mungkin bekerja ... (skill sed saya sangat berkarat, jadi ini mungkin perlu bekerja)
Tanda "," tidak ada dalam baris te colsep. Headep off dan linesize X mungkin berguna. Edit jawabannya dan saya akan menerimanya.
Daniel C. Sobral
5
Perintah sed adalah: cat myfile.csv | sed -e 's / [\ t] * | / | / g; s / | [] * / | / g '> myfile.csv. Bagaimanapun, Oracle benar-benar menyebalkan.
Stan
2
Dan untuk mendapatkan header dengan nama kolom menggunakan set pagesize 1000bukannya 0. Dalam komentar saya sebelumnya, Anda tidak dapat mengarahkan ke file yang sama: cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv.
Stan
1
Saya disaring kekosongan dan strip digunakan untuk garis bawah dengan grepdan trseperti ini grep -v -- ----- myfile.csv | tr -d [:blank:] > myfile.csv.
ixe013
1
@slayernoah perintah spool dapat mengambil jalur direktori dan nama file, sehingga Anda dapat menentukan dengan tepat di mana file output akan ditempatkan. Kalau tidak, itu akan tergantung pada lokasi di mana Anda mengeksekusi skrip.
Gabe
35
Saya menggunakan perintah ini untuk skrip yang mengekstrak data untuk tabel dimensi (DW). Jadi, saya menggunakan sintaks berikut:
set colsep '|'set echo offset feedback offset linesize 1000set pagesize 0set sqlprompt ''set trimspool onset headsep off
spool output.datselect'|',<table>.*,'|'from<table>where<conditions>
spool off
Dan bekerja. Saya tidak menggunakan sed untuk memformat file output.
Saya perlu spool file CSV dari SQLPLUS, tetapi hasilnya memiliki 250 kolom.
Apa yang saya lakukan untuk menghindari pemformatan output SQLPLUS yang mengganggu:
set linesize 9999set pagesize 50000
spool myfile.csvselect xfrom(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 xfrom(... here is the "core"select));
spool off
masalahnya adalah Anda akan kehilangan nama header kolom ...
Anda dapat menambahkan ini:
set heading off
spool myfile.csvselect 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 xfrom(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 xfrom(... here is the "core"select));
spool off
Saya tahu ini agak hardcore, tapi itu bekerja untuk saya ...
Apakah kita perlu ||untuk subquery juga ?, Saya rasa itu tidak diperlukan untuk subquery. tapi ya itu diperlukan untuk pemilihan utama.
davidb
Untuk apa ekstra luar select x? Ini seharusnya bekerja tanpanya. @davidb, Anda benar bahwa rangkaian tidak diperlukan dalam subquery bagian dalam primer, tetapi aliasing semua kolom sebagai col1, col2 ... dll. diperlukan di sana.
Amit Naidu
18
Dengan versi alat klien yang lebih baru, ada beberapa opsi untuk memformat output kueri. Sisanya adalah untuk menggulungnya ke file atau menyimpan output sebagai file tergantung pada alat klien. Berikut ini beberapa caranya:
SQL * Plus
Menggunakan perintah SQL * Plus Anda bisa memformat untuk mendapatkan output yang Anda inginkan. Gunakan SPOOL untuk menggulung output ke file.
Saya tahu ini adalah utas lama, namun saya perhatikan bahwa tidak ada yang menyebutkan opsi garis bawah, yang dapat menghapus garis bawah di bawah judul kolom.
set pagesize 50000--50k is the max as of 12cset linesize 10000set trimspool on--remove trailing blankspacesset underline off--remove the dashes/underlines under the col headersset colsep ~select*from DW_TMC_PROJECT_VW;
Tangkapan bagus pada opsi garis bawah, membutuhkan yang itu.
knockando
Sangat menyenangkan jika Anda ingin csv dengan baris atas yang berisi judul / judul untuk setiap kolom. Ini akan membantu siapa saja yang mungkin ingin melihat file csv, dan mencari tahu apa yang mereka lihat, dll ...
Doc
10
Itu mentah, tapi:
set pagesize 0 linesize 500 trimspool on feedback off echo offselect'"'|| empno ||'","'|| ename ||'","'|| deptno ||'"'as textfrom emp
spool emp.csv/
spool off
Anda dapat secara eksplisit memformat kueri untuk menghasilkan string yang dibatasi dengan sesuatu di sepanjang baris:
select'"'||foo||'","'||bar||'"'from tab
Dan mengatur opsi output yang sesuai. Sebagai pilihan, variabel COLSEP pada SQLPlus akan memungkinkan Anda menghasilkan file yang dibatasi tanpa harus secara eksplisit menghasilkan string dengan bidang yang digabungkan bersama. Namun, Anda harus memberi tanda kutip di sekitar string pada kolom apa pun yang mungkin berisi karakter koma yang disematkan.
Saya pernah menulis skrip SQL * Plus kecil yang menggunakan dbms_sqldan dbms_outputuntuk membuat csv (sebenarnya ssv). Anda dapat menemukannya di repositori githup saya .
Anda harus menyadari bahwa nilai-nilai bidang dapat berisi koma dan karakter kutipan, sehingga beberapa jawaban yang disarankan tidak akan berfungsi, karena file output CSV tidak benar. Untuk mengganti karakter kutip dalam bidang, dan menggantinya dengan karakter kutip ganda, Anda dapat menggunakan fungsi REPLACE yang disediakan oracle, untuk mengubah kutipan tunggal menjadi kutipan ganda.
set echo offset heading offset feedback offset linesize 1024-- or some other value, big enoughset pagesize 50000set verify offset trimspool on
spool output.csv
select trim('"'|| replace(col1,'"','""')||'","'|| replace(col2,'"','""')||'","'|| replace(coln,'"','""')||'"')-- etc. for all the columnsfrom yourtable
/
spool off
Atau, jika Anda ingin karakter kutipan tunggal untuk bidang:
set echo offset heading offset feedback offset linesize 1024-- or some other value, big enoughset pagesize 50000set verify offset trimspool on
spool output.csv
select trim('"'|| replace(col1,'''','''''')||'","'|| replace(col2,'''','''''')||'","'|| replace(coln,'''','''''')||'"')-- etc. for all the columnsfrom yourtable
/
spool off
Gunakan vi atau vim untuk menulis sql, gunakan colsep dengan kontrol-A (in vi dan vim mendahului ctrl-A dengan ctrl-v). Pastikan untuk mengatur garis dan halaman ke sesuatu yang rasional dan nyalakan trimspool dan trimout.
gulung ke file. Kemudian...
sed -e 's/,/;/g'-e 's/ *{ctrl-a} */,/g'{spooled file}> output.csv
Hal sed itu bisa dijadikan naskah. "*" Sebelum dan sesudah ctrl-A meremas semua ruang yang tidak berguna. Bukankah luar biasa bahwa mereka repot-repot mengaktifkan output html dari sqlplus tetapi BUKAN csv asli ?????
Saya melakukannya dengan cara ini karena menangani koma dalam data. Saya mengubahnya menjadi semi-titik dua.
Ini gagal dalam tes "Saya harus menggunakan SQLPlus".
Daniel C. Sobral
0
Ada masalah menggunakan sqlplus untuk membuat file csv. Jika Anda ingin tajuk kolom hanya sekali dalam output dan ada ribuan atau jutaan baris, Anda tidak dapat mengatur ukuran halaman cukup besar untuk tidak mendapatkan pengulangan. Solusinya adalah mulai dengan pagesize = 50 dan parsing header, lalu keluarkan pilih lagi dengan pagesize = 0 untuk mendapatkan data. Lihat skrip bash di bawah ini:
#!/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/nullset 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/nullset 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
}
Jawaban:
Jika Anda menggunakan 12.2, Anda bisa mengatakannya
sumber
Anda juga bisa menggunakan yang berikut ini, meskipun itu memperkenalkan spasi antar bidang.
Output akan seperti:
Ini akan jauh lebih membosankan daripada mengetik semua bidang dan menggabungkannya dengan koma. Anda bisa menindaklanjutinya dengan skrip sed sederhana untuk menghapus spasi putih yang muncul sebelum koma, jika Anda mau.
Sesuatu seperti ini mungkin bekerja ... (skill sed saya sangat berkarat, jadi ini mungkin perlu bekerja)
sumber
set pagesize 1000
bukannya 0. Dalam komentar saya sebelumnya, Anda tidak dapat mengarahkan ke file yang sama:cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv
.grep
dantr
seperti inigrep -v -- ----- myfile.csv | tr -d [:blank:] > myfile.csv
.Saya menggunakan perintah ini untuk skrip yang mengekstrak data untuk tabel dimensi (DW). Jadi, saya menggunakan sintaks berikut:
Dan bekerja. Saya tidak menggunakan sed untuk memformat file output.
sumber
Saya melihat masalah yang sama ...
Saya perlu spool file CSV dari SQLPLUS, tetapi hasilnya memiliki 250 kolom.
Apa yang saya lakukan untuk menghindari pemformatan output SQLPLUS yang mengganggu:
masalahnya adalah Anda akan kehilangan nama header kolom ...
Anda dapat menambahkan ini:
Saya tahu ini agak hardcore, tapi itu bekerja untuk saya ...
sumber
||
untuk subquery juga ?, Saya rasa itu tidak diperlukan untuk subquery. tapi ya itu diperlukan untuk pemilihan utama.select x
? Ini seharusnya bekerja tanpanya. @davidb, Anda benar bahwa rangkaian tidak diperlukan dalam subquery bagian dalam primer, tetapi aliasing semua kolom sebagai col1, col2 ... dll. diperlukan di sana.Dengan versi alat klien yang lebih baru, ada beberapa opsi untuk memformat output kueri. Sisanya adalah untuk menggulungnya ke file atau menyimpan output sebagai file tergantung pada alat klien. Berikut ini beberapa caranya:
Menggunakan perintah SQL * Plus Anda bisa memformat untuk mendapatkan output yang Anda inginkan. Gunakan SPOOL untuk menggulung output ke file.
Sebagai contoh,
Atau, Anda bisa menggunakan petunjuk baru di SQL Developer .
/*csv*/
Misalnya, dalam Versi Pengembang SQL saya 3.2.20.10 :
Sekarang Anda bisa menyimpan output ke file.
Baru di SQL Developer versi 4.1, gunakan perintah berikut seperti sqlplus dan jalankan sebagai skrip. Tidak perlu petunjuk dalam kueri.
Sekarang Anda bisa menyimpan output ke file.
sumber
Saya tahu ini adalah utas lama, namun saya perhatikan bahwa tidak ada yang menyebutkan opsi garis bawah, yang dapat menghapus garis bawah di bawah judul kolom.
sumber
Itu mentah, tapi:
sumber
Anda dapat secara eksplisit memformat kueri untuk menghasilkan string yang dibatasi dengan sesuatu di sepanjang baris:
Dan mengatur opsi output yang sesuai. Sebagai pilihan, variabel COLSEP pada SQLPlus akan memungkinkan Anda menghasilkan file yang dibatasi tanpa harus secara eksplisit menghasilkan string dengan bidang yang digabungkan bersama. Namun, Anda harus memberi tanda kutip di sekitar string pada kolom apa pun yang mungkin berisi karakter koma yang disematkan.
sumber
lebih suka menggunakan "set colsep" di sqlplus prompt daripada mengedit nama col satu per satu. Gunakan sed untuk mengedit file output.
sumber
Saya pernah menulis skrip SQL * Plus kecil yang menggunakan
dbms_sql
dandbms_output
untuk membuat csv (sebenarnya ssv). Anda dapat menemukannya di repositori githup saya .sumber
Anda harus menyadari bahwa nilai-nilai bidang dapat berisi koma dan karakter kutipan, sehingga beberapa jawaban yang disarankan tidak akan berfungsi, karena file output CSV tidak benar. Untuk mengganti karakter kutip dalam bidang, dan menggantinya dengan karakter kutip ganda, Anda dapat menggunakan fungsi REPLACE yang disediakan oracle, untuk mengubah kutipan tunggal menjadi kutipan ganda.
Atau, jika Anda ingin karakter kutipan tunggal untuk bidang:
sumber
trim()
tidak perlu.Gunakan vi atau vim untuk menulis sql, gunakan colsep dengan kontrol-A (in vi dan vim mendahului ctrl-A dengan ctrl-v). Pastikan untuk mengatur garis dan halaman ke sesuatu yang rasional dan nyalakan trimspool dan trimout.
gulung ke file. Kemudian...
Hal sed itu bisa dijadikan naskah. "*" Sebelum dan sesudah ctrl-A meremas semua ruang yang tidak berguna. Bukankah luar biasa bahwa mereka repot-repot mengaktifkan output html dari sqlplus tetapi BUKAN csv asli ?????
Saya melakukannya dengan cara ini karena menangani koma dalam data. Saya mengubahnya menjadi semi-titik dua.
sumber
Ada masalah menggunakan sqlplus untuk membuat file csv. Jika Anda ingin tajuk kolom hanya sekali dalam output dan ada ribuan atau jutaan baris, Anda tidak dapat mengatur ukuran halaman cukup besar untuk tidak mendapatkan pengulangan. Solusinya adalah mulai dengan pagesize = 50 dan parsing header, lalu keluarkan pilih lagi dengan pagesize = 0 untuk mendapatkan data. Lihat skrip bash di bawah ini:
sumber
Saya menulis skrip murni SQLPlus ini untuk membuang tabel ke CSV pada tahun 1994.
Seperti tercantum dalam komentar skrip, seseorang di Oracle memasukkan skrip saya ke dalam catatan Dukungan Oracle, tetapi tanpa atribusi.
https://github.com/jkstill/oracle-script-lib/blob/master/sql/dump.sql
Script juga membangun file kontrol dan file parameter untuk SQL * LOADER
sumber
sumber
Anda bisa menggunakan petunjuk csv. Lihat contoh berikut:
sumber