SQLPLUS를 사용하여 CSV 형식 파일로 스풀링하려면 어떻게합니까?


143

일부 쿼리를 CSV 출력 형식으로 추출하고 싶습니다. 불행히도, 멋진 SQL 클라이언트 또는 언어를 사용하여 사용할 수는 없습니다. SQLPLUS를 사용해야합니다.

어떻게합니까?


@BobC가 제공 한 정답으로 표시하십시오. 파일을 인쇄하기위한 스풀 명령이 누락되었지만 데이터를 csv 형식으로 내보내는 가장 간단한 솔루션입니다.
rlar

답변:


28

12.2를 사용하는 경우 간단히 말할 수 있습니다.

set markup csv on
spool myfile.csv

누구든지 에코를 끄는 방법을 알고 있습니까? 명백한 "세트 에코 해제"가 작동하지 않는 것 같습니다.
쿼터니언

이것이 스크립트를 실행하고 파일에 쓰기 때문이라고 가정하면 "만약 종료"
BobC

155

필드 사이에 공백이 있지만 다음을 사용할 수도 있습니다.

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 

","가 col colep 라인에 없습니다. 또한 headsep off 및 linesize X가 유용 할 것입니다. 답변을 수정하면 수락하겠습니다.
Daniel C. Sobral

5
sed 명령은 다음과 같습니다. cat myfile.csv | sed -e 's / [\ t] * | / | / g; s / | [] * / | / g '> myfile.csv. 어쨌든, 오라클은 정말 짜증납니다.
Stan

2
그리고 열 이름을 가진 헤더를 얻으려면 set pagesize 10000 대신 사용하십시오. 이전 주석에서 동일한 파일로 리디렉션 할 수 없습니다 : cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv.
Stan

1
나는 이것 grep과 밑줄을 긋는 데 사용 된 공백과 대시를 걸러 냈습니다 . trgrep -v -- ----- myfile.csv | tr -d [:blank:] > myfile.csv
ixe013

1
@slayernoah spool 명령은 디렉토리 경로와 파일 이름을 사용할 수 있으므로 출력 파일이 배치 될 위치를 정확하게 지정할 수 있습니다. 그렇지 않으면 스크립트를 실행하는 위치에 따라 다릅니다.
Gabe

35

차원 테이블 (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를 사용하지 않습니다.


24

비슷한 문제가 있습니다 ...

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

나는 그것이 다소 하드 코어라는 것을 알고 있지만 그것은 나를 위해 작동합니다 ...


||하위 쿼리도 필요합니까 ?, 하위 쿼리에 필요 하다고 생각하지 않습니다. 그러나 기본 선택에는 필수입니다.
davidb

여분의 아우터는 무엇입니까 select x? 이것은 그것없이 작동해야합니다. @ davidb, 기본 내부 하위 쿼리에는 연결이 필요하지 않지만 모든 열의 별칭을 col1, col2 ... etc로 지정하는 것이 맞습니다. 거기에 필요합니다.
Amit Naidu

18

최신 버전의 클라이언트 도구에는 쿼리 출력을 형식화하는 여러 옵션이 있습니다. 나머지는 클라이언트 도구에 따라 파일로 스풀하거나 출력을 파일로 저장하는 것입니다. 몇 가지 방법이 있습니다.

  • 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>
  • 4.1 이전의 SQL 개발자 버전

또는 SQL Developer 에서 새로운 힌트 를 사용할 수 있습니다 ./*csv*/

/*csv*/

예를 들어, SQL Developer Version 3.2.20.10에서 :

여기에 이미지 설명을 입력하십시오

이제 출력을 파일로 저장할 수 있습니다.

  • SQL 개발자 버전 4.1

SQL Developer 버전 4.1의 새로운 기능으로 sqlplus 명령과 같이 다음을 사용하고 스크립트로 실행하십시오. 쿼리에 힌트가 필요하지 않습니다.

SET SQLFORMAT csv

이제 출력을 파일로 저장할 수 있습니다.


12

나는 이것이 오래된 스레드라는 것을 알고 있지만 아무도 열 제목 아래에서 밑줄을 제거 할 수있는 밑줄 옵션을 언급하지 않았다는 것을 알았습니다.

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;

밑줄 옵션을 잘 잡았습니다.
knockando

각 열의 제목 / 제목이 포함 된 상단 행이있는 csv를 원한다면 좋습니다. csv 파일을 보거나보고있는 내용 등을 파악하려는 사람이라면 누구나 도움이 될 것입니다.
Doc

10

조잡하지만,

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

쿼리를 명시 적으로 형식화하여 다음 줄을 따라 구분 된 문자열을 생성 할 수 있습니다.

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

그리고 출력 옵션을 적절히 설정하십시오. 옵션으로 SQLPlus의 COLSEP 변수를 사용하면 필드가 함께 연결된 문자열을 명시 적으로 생성하지 않고도 구분 된 파일을 생성 할 수 있습니다. 그러나 포함 된 쉼표 문자가 포함 된 열에서 문자열을 따옴표로 묶어야합니다.


4

col 이름을 하나씩 편집하는 대신 sqlplus 프롬프트에서 "set colsep"을 사용하는 것을 선호합니다. sed를 사용하여 출력 파일을 편집하십시오.

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


2

필드 값에 쉼표와 따옴표가 포함될 수 있으므로 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()불필요합니다.
Amit Naidu

1

vi 또는 vim을 사용하여 SQL을 작성하고 colsep를 control-A와 함께 사용하십시오 (vi 및 vim에서 ctrl-A 앞에 ctrl-v가 있음). 선 크기와 페이지 크기를 합리적인 것으로 설정하고 다듬기 및 자르기를 켭니다.

파일로 스풀링하십시오. 그때...

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

그 sed는 스크립트로 바꿀 수 있습니다. ctrl-A 전후의 "*"는 쓸모없는 모든 공간을 짜냅니다. 그들이 sqlplus에서 HTML 출력을 사용하도록 귀찮게했지만 네이티브 csv가 아닌 것이 좋지 않습니까 ?????

데이터에서 쉼표를 처리하기 때문에이 방법으로 수행합니다. 세미콜론으로 바꿉니다.


3
"SQLPlus를 사용해야합니다"테스트가 실패합니다.
Daniel C. Sobral

0

sqlplus를 사용하여 CSV 파일을 작성하는 데 문제가 있습니다. 출력에서 열 머리글을 한 번만 원하고 수천 또는 수백만 행이있는 경우 반복되지 않을만큼 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

1994 년에 테이블을 CSV로 덤프하기 위해이 순수 SQLPlus 스크립트를 작성했습니다.

스크립트 주석에서 언급했듯이 Oracle의 누군가가 내 스크립트를 Oracle 지원 노트에 표시하지만 속성은 표시하지 않았습니다.

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

스크립트는 또한 SQL * LOADER에 대한 제어 파일 및 매개 변수 파일도 빌드합니다.



-3

csv 힌트를 사용할 수 있습니다. 다음 예를 참조하십시오.

select /*csv*/ table_name, tablespace_name
from all_tables
where owner = 'SYS'
and tablespace_name is not null;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.