SQLPLUS kullanarak CSV biçimli bir dosyaya nasıl biriktiririm?


143

Bazı sorguları bir CSV çıktı biçimine ayıklamak istiyorum. Ne yazık ki, bunu yapmak için herhangi bir süslü SQL istemcisi veya herhangi bir dil kullanamıyorum. SQLPLUS kullanmalıyım.

Nasıl yaparım?


Lütfen @BobC tarafından verilen yanıtı doğru olarak işaretleyin. Dosyayı yazdırmak için spool komutu eksik ama verileri csv formatında dışa aktarmak için en basit çözüm.
rlar

Yanıtlar:


28

12.2 kullanıyorsanız,

set markup csv on
spool myfile.csv

Eko nasıl kapatılacağını bilen var mı, bariz "set echo off" bununla çalışmıyor gibi görünüyor?
Quaternion

Bunun bir komut dosyası yürüttüğünüz ve bir dosyaya yazdığınızdan yola çıkarak, "termout'u kapatmanız" gerekir
BobC

155

Alanlar arasında boşluk bırakmasına rağmen aşağıdakileri de kullanabilirsiniz.

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;

Çıktı aşağıdaki gibi olacaktır:

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

Bu, tüm alanları yazmaktan ve virgülle birleştirmekten çok daha az sıkıcı olacaktır. İsterseniz, virgülden önce görünen boşlukları kaldırmak için basit bir sed komut dosyası kullanabilirsiniz.

Böyle bir şey işe yarayabilir ... (sed becerilerim çok paslı, bu yüzden muhtemelen işe ihtiyaç duyacak)

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

Colsep satırında "," eksik. Ayrıca headsep off ve linesize X'in de faydalı olması muhtemeldir. Cevabı düzenlerseniz kabul edeceğim.
Daniel C. Sobral

5
Sed komutu: cat myfile.csv | sed -e 's / [\ t] * | / | / g; s / | [] * / | / g '> dosyam.csv. Her neyse, Oracle gerçekten berbat.
Stan

2
Ve sütun adlarını içeren bir başlık kullanmak almak için set pagesize 1000benim önceki yorum olarak 0'a yerine, aynı dosyaya yönlendirme yapamaz: cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv.
Stan

1
Ben boşlukları ile çizili kullanılan tire filtre grepve trbunun gibi grep -v -- ----- myfile.csv | tr -d [:blank:] > myfile.csv.
ixe013 17:12

1
@slayernoah spool komutu bir dizin yolunu ve dosya adını alabilir, böylece çıktı dosyasının tam olarak nereye yerleştirileceğini belirleyebilirsiniz. Aksi takdirde, komut dosyasını yürüttüğünüz konuma bağlıdır.
Gabe

35

Boyutsal tablolar (DW) için veri ayıklayan komut dosyaları için bu komutu kullanın. Bu yüzden, aşağıdaki sözdizimini kullanıyorum:

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

Ve çalışıyor. Çıktı dosyasını biçimlendirmek için sed kullanmıyorum.


24

Benzer bir sorun görüyorum ...

SQLPLUS CSV dosyasını biriktirmek gerekiyor, ancak çıkış 250 sütun var.

Ne can sıkıcı SQLPLUS çıktı biçimlendirme önlemek için yaptım:

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

sorun, sütun başlığı adlarını kaybetmenizdir ...

bunu ekleyebilirsiniz:

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

Çok sert olduğunu biliyorum, ama benim için çalışıyor ...


||alt sorgu için de ihtiyacımız var mı?, alt sorgular için gerekli olduğunu sanmıyorum. ancak evet birincil seçim için gereklidir.
davidb

Ekstra dış kısım ne select xiçin? Bu onsuz çalışmalı. @davidb, birincil iç alt sorguda birleştirme gerekmediğini, ancak tüm sütunları col1, col2 ... vb. olarak takma konusunda haklısınız. orada gereklidir.
Amit Naidu

18

İstemci araçlarının daha yeni sürümlerinde, sorgu çıktısını biçimlendirmek için birden çok seçenek vardır. Geri kalanı onu bir dosyaya biriktirmek veya çıktıyı istemci aracına bağlı olarak bir dosya olarak kaydetmek. İşte birkaç yol:

  • SQL * Plus,

SQL * Plus komutlarını kullanarak istediğiniz çıktıyı elde etmek için biçimlendirebilirsiniz. Çıktıyı bir dosyaya biriktirmek için SPOOL'u kullanın .

Örneğin,

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 Geliştirici Sürümü 4.1 öncesi

Alternatif olarak, yeni kullanabilirsiniz ipucu içinde SQL Developer ./*csv*/

/*csv*/

Örneğin, SQL Geliştirici Sürüm 3.2.20.10'da :

resim açıklamasını buraya girin

Şimdi çıktıyı bir dosyaya kaydedebilirsiniz.

  • SQL Geliştirici Sürüm 4.1

SQL Developer sürüm 4.1'de yeni olan, sqlplus komutu gibi aşağıdakileri kullanın ve komut dosyası olarak çalıştırın. Sorguda ipucuna gerek yok.

SET SQLFORMAT csv

Şimdi çıktıyı bir dosyaya kaydedebilirsiniz.


12

Bu eski bir iş parçacığı olduğunu biliyorum, ancak kimse sütun başlıkları altında alt çizgi kaldırabilirsiniz alt çizgi seçeneği bahsetti fark ettim.

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;

Alt çizgi seçeneği güzel yakalamak, buna ihtiyaç vardı.
17'de knockando

Her sütun için başlık / başlıkları içeren bir üst sıra ile bir csv istiyorsanız güzel. Onlar vb ..., bakıyorsun ne csv dosyasını görüntülemek isteyebilirsiniz herkes ve şekil yardımcı olacağını
Doktor

10

Bu kaba, ama:

set pagesize 0 linesize 500 trimspool on feedback off echo off

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

spool emp.csv
/
spool off

7

Sorguyu, satırları boyunca bir şeyle ayrılmış bir dize oluşturmak için açıkça biçimlendirebilirsiniz:

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

Ve çıkış seçeneklerini uygun şekilde ayarlayın. Bir seçenek olarak, SQLPlus üzerindeki COLSEP değişkeni, açık bir şekilde bir araya getirilmiş alanlarla bir dize oluşturmak zorunda kalmadan sınırlandırılmış dosyalar oluşturmanıza izin verir. Ancak, gömülü virgül karakterleri içerebilecek tüm sütunlara dizelerin içine tırnak koymanız gerekir.


4

col adını birer birer düzenlemek yerine sqlplus komut isteminde "set colsep" kullanmayı tercih edin. Çıktı dosyasını düzenlemek için sed tuşunu kullanın.

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

3

Bir zamanlar kullanan dbms_sqlve dbms_outputbir csv (aslında bir ssv) oluşturmak için küçük bir SQL * Plus komut dosyası yazdım. Bunu githup deposumda bulabilirsiniz .


2

Alanların değerlerinin virgül ve tırnak karakterleri içerebileceğinin farkında olmalısınız, bu nedenle CSV çıktı dosyası doğru olmayacağından önerilen yanıtlardan bazıları çalışmayacaktır. Bir alandaki tırnak karakterlerini değiştirmek ve bunu çift tırnak karakteriyle değiştirmek için, kehanetin sağladığı DEĞİŞTİR işlevini kullanarak tek bir alıntıyı çift tırnak olarak değiştirin.

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

Veya alanlar için tek tırnak karakteri istiyorsanız:

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()Gereksizdir.
Amit Naidu

1

Sql yazmak için vi veya vim kullanın, bir kontrol-A ile colsep kullanın (vi ve vim'de ctrl-A'dan önce bir ctrl-v ile). Satır boyutunu ve sayfa boyutunu rasyonel bir şeye ayarladığınızdan ve trimspool ve trimout'u açtığınızdan emin olun.

bir dosyaya biriktirin. Sonra...

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

O sed şey bir senaryoya dönüştürülebilir. Ctrl-A öncesi ve sonrası "*" tüm gereksiz alanları sıkar. Onlar sqlplus html çıkışı etkinleştirmek için rahatsız ama yerel csv DEĞİL harika değil mi ?????

Bunu bu şekilde yapıyorum çünkü verilerde virgül kullanıyor. Onları yarım sütuna çeviriyorum.


3
Bu, "SQLPlus kullanmalıyım" sınamasında başarısız olur.
Daniel

0

Csv dosyaları oluşturmak için sqlplus kullanırken bir sorun var. Sütun başlıklarının çıktıda yalnızca bir kez olmasını ve binlerce veya milyonlarca satır olmasını istiyorsanız, yinelenmeyecek kadar büyük sayfa boyutu ayarlayamazsınız. Çözüm, pagesize = 50 ile başlayıp başlıkları ayrıştırın, ardından verileri almak için select'i tekrar pagesize = 0 ile yayınlayın. Aşağıdaki bash betiğine bakın:

#!/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
}



-3

Csv ipucunu kullanabilirsiniz. Aşağıdaki örneğe bakın:

select /*csv*/ table_name, tablespace_name
from all_tables
where owner = 'SYS'
and tablespace_name is not null;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.