Wie spule ich mit SQLPLUS in eine CSV-formatierte Datei?

143

Ich möchte einige Abfragen in ein CSV-Ausgabeformat extrahieren. Leider kann ich dafür keinen ausgefallenen SQL-Client oder eine andere Sprache verwenden. Ich muss SQLPLUS verwenden.

Wie mache ich es?

Daniel C. Sobral
quelle
Bitte markieren Sie die Antwort von @BobC als richtig. Es fehlt der Befehl spool zum Drucken der Datei, aber es ist die einfachste Lösung, Daten im CSV-Format zu exportieren.
Rlar

Antworten:

28

Wenn Sie 12.2 verwenden, können Sie einfach sagen

set markup csv on
spool myfile.csv
BobC
quelle
Weiß jemand, wie man das Echo ausschaltet, das offensichtliche "Echo ausschalten" scheint damit nicht zu funktionieren?
Quaternion
Angenommen, dies liegt daran, dass Sie ein Skript ausführen und in eine Datei schreiben, sollten Sie einfach "termout off" setzen
BobC
155

Sie können auch Folgendes verwenden, obwohl Leerzeichen zwischen Feldern eingefügt werden.

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;

Die Ausgabe lautet wie folgt:

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

Dies wäre viel weniger mühsam, als alle Felder auszutippen und mit Kommas zu verknüpfen. Wenn Sie möchten, können Sie ein einfaches sed-Skript verwenden, um Leerzeichen zu entfernen, die vor einem Komma angezeigt werden.

So etwas könnte funktionieren ... (meine Fähigkeiten sind sehr verrostet, daher wird dies wahrscheinlich Arbeit erfordern)

sed 's/\s+,/,/' myfile.csv 
Gabe
quelle
Das "," fehlt in der Spalte. Auch Headsep Off und Liniengröße X sind wahrscheinlich nützlich. Bearbeiten Sie die Antwort und ich werde es akzeptieren.
Daniel C. Sobral
5
Der Befehl sed lautet: cat myfile.csv | sed -es / [\ t] * | / | / g; s / | [] * / | / g '> myfile.csv. Wie auch immer, Oracle ist wirklich scheiße.
Stan
2
Und um einen Header mit den Spaltennamen zu erhalten, verwenden Sie set pagesize 1000anstelle von 0. In meinem vorherigen Kommentar können Sie nicht zur gleichen Datei umleiten : cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv.
Stan
1
Ich filtriert , um die Zuschnitte und die zu unterstreichen verwendet Striche mit grepund trwie diese grep -v -- ----- myfile.csv | tr -d [:blank:] > myfile.csv.
ixe013
1
@slayernoah Der Befehl spool kann einen Verzeichnispfad und einen Dateinamen annehmen, sodass Sie genau angeben können, wo die Ausgabedatei abgelegt werden soll. Andernfalls hängt es vom Speicherort ab, an dem Sie das Skript ausführen.
Gabe
35

Ich verwende diesen Befehl für Skripte, die Daten für Dimensionstabellen (DW) extrahieren. Daher verwende ich die folgende Syntax:

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

Und funktioniert. Ich verwende sed nicht zum Formatieren der Ausgabedatei.

Hallison Batista
quelle
24

Ich sehe ein ähnliches Problem ...

Ich muss eine CSV-Datei aus SQLPLUS spoolen, aber die Ausgabe enthält 250 Spalten.

Was ich getan habe, um die lästige Formatierung der SQLPLUS-Ausgabe zu vermeiden:

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

Das Problem ist, dass Sie Spaltenüberschriften verlieren ...

Sie können dies hinzufügen:

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

Ich weiß, dass es ein bisschen Hardcore ist, aber es funktioniert für mich ...

Karlos
quelle
brauchen wir auch ||für Unterabfragen? Ich glaube nicht, dass es für die Unterabfragen erforderlich ist. aber ja, es ist für die primäre Auswahl erforderlich.
Davidb
Wofür ist das zusätzliche Äußere select x? Dies sollte ohne funktionieren. @davidb, Sie haben Recht, dass die Verkettung in der primären inneren Unterabfrage nicht erforderlich ist, sondern alle Spalten als col1, col2 ... usw. aliasiert. ist dort erforderlich.
Amit Naidu
18

Bei neueren Versionen von Client-Tools gibt es mehrere Optionen zum Formatieren der Abfrageausgabe. Der Rest besteht darin, es in eine Datei zu spulen oder die Ausgabe je nach Client-Tool als Datei zu speichern. Hier sind einige der Möglichkeiten:

  • SQL * Plus

Mit den SQL * Plus-Befehlen können Sie formatieren, um die gewünschte Ausgabe zu erhalten. Verwenden Sie SPOOL, um die Ausgabe in eine Datei zu spoolen .

Beispielsweise,

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 Version vor 4.1

Alternativ können Sie den neuen Hinweis in SQL Developer verwenden ./*csv*/

/*csv*/

Zum Beispiel in meinem SQL Developer Version 3.2.20.10 :

Geben Sie hier die Bildbeschreibung ein

Jetzt können Sie die Ausgabe in einer Datei speichern.

  • SQL Developer Version 4.1

Verwenden Sie in SQL Developer Version 4.1 den folgenden Befehl wie den Befehl sqlplus und führen Sie ihn als Skript aus. Der Hinweis in der Abfrage ist nicht erforderlich.

SET SQLFORMAT csv

Jetzt können Sie die Ausgabe in einer Datei speichern.

Lalit Kumar B.
quelle
12

Ich weiß, dass dies ein alter Thread ist, aber ich habe festgestellt, dass niemand die Unterstreichungsoption erwähnt hat, mit der die Unterstreichungen unter den Spaltenüberschriften entfernt werden können.

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;
Doc
quelle
Netter Fang bei der Unterstreichungsoption, brauchte diesen.
Knockando
Es ist schön, wenn Sie eine CSV mit einer oberen Zeile möchten, die den Titel / die Überschriften für jede Spalte enthält. Es würde jedem helfen, der die CSV-Datei anzeigen und herausfinden möchte, was er gerade sieht, usw.
Doc
10

Es ist grob, aber:

set pagesize 0 linesize 500 trimspool on feedback off echo off

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

spool emp.csv
/
spool off
Tony Andrews
quelle
7

Sie können die Abfrage explizit formatieren, um eine begrenzte Zeichenfolge mit folgenden Elementen zu erstellen:

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

Und richten Sie die Ausgabeoptionen entsprechend ein. Optional können Sie mit der COLSEP-Variablen in SQLPlus begrenzte Dateien erstellen, ohne explizit eine Zeichenfolge mit den miteinander verketteten Feldern generieren zu müssen. Sie müssen jedoch Zeichenfolgen in Spalten, die möglicherweise eingebettete Kommazeichen enthalten, in Anführungszeichen setzen.

ConcernedOfTunbridgeWells
quelle
4

Verwenden Sie lieber "set colsep" in der sqlplus-Eingabeaufforderung, anstatt den Spaltennamen einzeln zu bearbeiten. Verwenden Sie sed, um die Ausgabedatei zu bearbeiten.

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

Ich habe einmal ein kleines SQL * Plus-Skript geschrieben, das eine CSV (eigentlich eine SSV) verwendet dbms_sqlund dbms_outputerstellt. Sie finden es in meinem Githup-Repository .

René Nyffenegger
quelle
2

Sie sollten sich bewusst sein, dass Werte von Feldern Kommas und Anführungszeichen enthalten können, sodass einige der vorgeschlagenen Antworten nicht funktionieren, da die CSV-Ausgabedatei nicht korrekt ist. Um Anführungszeichen in einem Feld zu ersetzen und durch das doppelte Anführungszeichen zu ersetzen, können Sie die von oracle bereitgestellte REPLACE-Funktion verwenden, um ein einfaches Anführungszeichen in ein doppeltes Anführungszeichen zu ändern.

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

Oder wenn Sie das einfache Anführungszeichen für die Felder möchten:

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
Rob Heusdens
quelle
Das trim()ist unnötig.
Amit Naidu
1

Verwenden Sie vi oder vim, um das SQL zu schreiben, verwenden Sie colsep mit einem Steuerelement-A (in vi und vim steht das Strg-A mit einem Strg-v vor). Stellen Sie sicher, dass die Linien- und Seitengröße auf etwas Rationales eingestellt ist, und aktivieren Sie Trimspool und Trimout.

spule es in eine Datei. Dann...

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

Das sed Ding kann in ein Skript verwandelt werden. Das "*" vor und nach Strg-A drückt alle nutzlosen Leerzeichen aus. Ist es nicht toll, dass sie sich die Mühe gemacht haben, die HTML-Ausgabe von sqlplus zu aktivieren, aber NICHT native csv ?????

Ich mache es so, weil es Kommas in den Daten behandelt. Ich verwandle sie in Semikolons.

Charles Stepp
quelle
3
Dies schlägt den Test "Ich muss SQLPlus verwenden" fehl.
Daniel C. Sobral
0

Es gibt ein Problem bei der Verwendung von sqlplus zum Erstellen von CSV-Dateien. Wenn Sie möchten, dass die Spaltenüberschriften nur einmal in der Ausgabe angezeigt werden und Tausende oder Millionen von Zeilen vorhanden sind, können Sie die Seitengröße nicht groß genug einstellen, um keine Wiederholung zu erhalten. Die Lösung besteht darin, mit Seitengröße = 50 zu beginnen und die Überschriften zu analysieren. Anschließend müssen Sie die Auswahl erneut mit Seitengröße = 0 ausführen, um die Daten abzurufen. Siehe Bash-Skript unten:

#!/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
}
Larry R. Irwin
quelle
0

Ich habe dieses reine SQLPlus-Skript geschrieben, um Tabellen 1994 in CSV zu sichern.

Wie in den Skriptkommentaren angegeben, hat jemand bei Oracle mein Skript in einen Oracle Support-Hinweis eingefügt, jedoch ohne Zuordnung.

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

Das Skript erstellt außerdem eine Steuerdatei und eine Parameterdatei für SQL * LOADER

Jared Still
quelle
-1
spool D:\test.txt

    select * from emp
    
    spool off
Satheeshkumar P.
quelle
-3

Sie könnten einen CSV-Hinweis verwenden. Siehe folgendes Beispiel:

select /*csv*/ table_name, tablespace_name
from all_tables
where owner = 'SYS'
and tablespace_name is not null;
Adilson Silva
quelle