Làm cách nào để tôi lưu vào tệp định dạng CSV bằng SQLPLUS?


143

Tôi muốn trích xuất một số truy vấn sang định dạng đầu ra CSV. Thật không may, tôi không thể sử dụng bất kỳ máy khách SQL ưa thích hoặc bất kỳ ngôn ngữ nào để làm điều đó. Tôi phải sử dụng SQLPLUS.

Tôi phải làm nó như thế nào?


Vui lòng, đánh dấu là chính xác câu trả lời được đưa ra bởi @BobC. Nó thiếu lệnh spool để in tệp nhưng nó là giải pháp đơn giản nhất để xuất dữ liệu ở định dạng csv.
rlar

Câu trả lời:


28

Nếu bạn đang sử dụng 12.2, bạn có thể nói một cách đơn giản

set markup csv on
spool myfile.csv

Có ai biết làm thế nào để bạn tắt tiếng vang, "tắt tiếng vang" rõ ràng dường như không hoạt động với điều này?
Đệ tứ

Giả sử rằng đây là bởi vì bạn đang thực hiện một kịch bản và viết vào một tập tin, bạn nên chỉ là "bộ termout off"
BobC

155

Bạn cũng có thể sử dụng như sau, mặc dù nó giới thiệu khoảng trắng giữa các trường.

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;

Đầu ra sẽ như sau:

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

Điều này sẽ ít tẻ nhạt hơn nhiều so với việc gõ ra tất cả các trường và nối chúng với dấu phẩy. Bạn có thể theo dõi với một tập lệnh sed đơn giản để xóa khoảng trắng xuất hiện trước dấu phẩy, nếu bạn muốn.

Một cái gì đó như thế này có thể hoạt động ... (kỹ năng sed của tôi rất gỉ, vì vậy điều này có thể sẽ cần làm việc)

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

"," Bị thiếu trong dòng te colsep. Ngoài ra headsep off và lineize X có thể sẽ hữu ích. Chỉnh sửa câu trả lời và tôi sẽ chấp nhận nó.
Daniel C. Sobral

5
Lệnh sed là: cat myfile.csv | sed -e 's / [\ t] * | / | / g; s / | [] * / | / g '> myfile.csv. Dù sao, Oracle thực sự hút.
Stan

2
Và để có được một tiêu đề với tên cột sử dụng set pagesize 1000thay vì 0. Trong nhận xét trước đây của tôi, bạn không thể chuyển hướng đến cùng một tệp : cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv.
Stan

1
Tôi đã lọc ra các khoảng trống và dấu gạch ngang được sử dụng để gạch chân greptrnhư thế này grep -v -- ----- myfile.csv | tr -d [:blank:] > myfile.csv.
ixe013

1
@slayernoah lệnh spool có thể lấy đường dẫn thư mục và tên tệp, để bạn có thể chỉ định chính xác vị trí tệp đầu ra sẽ được đặt. Nếu không, nó sẽ phụ thuộc vào vị trí mà bạn đang thực thi tập lệnh.
Gabe

35

Tôi sử dụng lệnh này cho các tập lệnh trích xuất dữ liệu cho các bảng chiều (DW). Vì vậy, tôi sử dụng cú pháp sau:

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

Và hoạt động. Tôi không sử dụng sed để định dạng tệp đầu ra.


24

Tôi thấy một vấn đề tương tự ...

Tôi cần phải lưu tệp CSV từ SQLPLUS, nhưng đầu ra có 250 cột.

Những gì tôi đã làm để tránh định dạng đầu ra SQLPLUS gây phiền nhiễu:

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

vấn đề là bạn sẽ mất tên tiêu đề cột ...

bạn có thể thêm cái này:

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

Tôi biết nó hơi khó, nhưng nó hiệu quả với tôi ...


chúng ta có cần ||cho truy vấn con không?, tôi không nghĩ rằng nó là bắt buộc cho các truy vấn con. nhưng có nó là cần thiết cho lựa chọn chính.
davidb

Bên ngoài thêm select xđể làm gì? Điều này sẽ làm việc mà không có nó. @davidb, bạn đã đúng rằng không cần phải ghép nối trong truy vấn con bên trong chính, nhưng đặt bí danh cho tất cả các cột là col1, col2 ... vv. được yêu cầu ở đó.
Amit N Nikol

18

Với các phiên bản mới hơn của công cụ máy khách, có nhiều tùy chọn để định dạng đầu ra truy vấn. Phần còn lại là để lưu nó vào một tệp hoặc lưu kết quả đầu ra dưới dạng tệp tùy thuộc vào công cụ máy khách. Dưới đây là một vài cách:

  • SQL * Plus

Sử dụng các lệnh SQL * Plus, bạn có thể định dạng để có đầu ra mong muốn. Sử dụng SPOOL để lưu kết quả đầu ra vào một tệp.

Ví dụ,

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>
  • Phiên bản dành cho nhà phát triển SQL trước 4.1

Ngoài ra, bạn có thể sử dụng gợi ý mới trong SQL Developer ./*csv*/

/*csv*/

Ví dụ: trong SQL Developer phiên bản 3.2.20.10 của tôi :

nhập mô tả hình ảnh ở đây

Bây giờ bạn có thể lưu đầu ra vào một tập tin.

  • Nhà phát triển SQL Phiên bản 4.1

Mới trong SQL Developer phiên bản 4.1, sử dụng lệnh sau giống như lệnh sqlplus và chạy dưới dạng tập lệnh. Không cần gợi ý trong truy vấn.

SET SQLFORMAT csv

Bây giờ bạn có thể lưu đầu ra vào một tập tin.


12

Tôi biết đây là một chủ đề cũ, tuy nhiên tôi nhận thấy rằng không ai đề cập đến tùy chọn gạch chân, có thể loại bỏ các gạch chân dưới tiêu đề cột.

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;

Đẹp bắt trên tùy chọn gạch chân, cần cái đó.
knando

Thật tuyệt nếu bạn muốn một csv với một hàng trên cùng có chứa tiêu đề / tiêu đề cho mỗi cột. Nó sẽ giúp bất cứ ai có thể muốn xem tệp csv và tìm ra những gì họ đang xem, v.v ...
Doc

10

Thật thô thiển, nhưng:

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

Bạn có thể định dạng rõ ràng truy vấn để tạo ra một chuỗi được phân tách bằng một cái gì đó dọc theo dòng:

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

Và thiết lập các tùy chọn đầu ra khi thích hợp. Như một tùy chọn, biến COLSEP trên SQLPlus sẽ cho phép bạn tạo các tệp được phân tách mà không cần phải tạo một chuỗi rõ ràng với các trường được nối với nhau. Tuy nhiên, bạn sẽ phải đặt dấu ngoặc kép quanh các chuỗi trên bất kỳ cột nào có thể chứa các ký tự dấu phẩy được nhúng.


4

thích sử dụng "set colsep" trong dấu nhắc sqlplus thay vì chỉnh sửa từng tên một col. Sử dụng sed để chỉnh sửa tập tin đầu ra.

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


2

Bạn nên lưu ý rằng các giá trị của các trường có thể chứa dấu phẩy và ký tự trích dẫn, vì vậy một số câu trả lời được đề xuất sẽ không hoạt động, vì tệp đầu ra CSV sẽ không chính xác. Để thay thế các ký tự trích dẫn trong một trường và thay thế nó bằng ký tự trích dẫn kép, bạn có thể sử dụng chức năng REPLACE mà oracle cung cấp, để thay đổi một trích dẫn thành trích dẫn kép.

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

Hoặc, nếu bạn muốn ký tự trích dẫn cho các trường:

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

Điều trim()không cần thiết.
Amit N Nikol

1

Sử dụng vi hoặc vim để viết sql, sử dụng colsep với control-A (trong vi và vim đứng trước ctrl-A với ctrl-v). Hãy chắc chắn để đặt kích thước đường thẳng và kích thước trang thành một cái gì đó hợp lý và bật trimspool và trimout.

spool nó ra một tập tin. Sau đó...

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

Điều đó sed có thể được biến thành một kịch bản. "*" Trước và sau ctrl-A sẽ loại bỏ tất cả các khoảng trống vô dụng. Chẳng phải thật tuyệt khi họ bận tâm kích hoạt đầu ra html từ sqlplus nhưng KHÔNG phải csv bản địa ?????

Tôi làm theo cách này vì nó xử lý dấu phẩy trong dữ liệu. Tôi biến chúng thành dấu chấm phẩy.


3
Điều này không thành công trong bài kiểm tra "Tôi phải sử dụng SQLPlus".
Daniel C. Sobral

0

Có một vấn đề khi sử dụng sqlplus để tạo tập tin csv. Nếu bạn muốn các tiêu đề cột chỉ một lần trong đầu ra và có hàng ngàn hoặc hàng triệu hàng, bạn không thể đặt kích thước trang đủ lớn để không lặp lại. Giải pháp là bắt đầu với Pagesize = 50 và phân tích các tiêu đề, sau đó đưa ra lựa chọn một lần nữa với Pagesize = 0 để lấy dữ liệu. Xem tập lệnh bash bên dưới:

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

Tôi đã viết tập lệnh SQLPlus hoàn toàn này để chuyển các bảng sang CSV vào năm 1994.

Như đã lưu ý trong các nhận xét về tập lệnh, một người nào đó tại Oracle đã đặt tập lệnh của tôi vào một ghi chú Hỗ trợ của Oracle, nhưng không có sự ghi nhận.

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

Kịch bản cũng xây dựng tệp điều khiển và tệp tham số cho SQL * LOADER



-3

Bạn có thể sử dụng gợi ý csv. Xem ví dụ sau:

select /*csv*/ table_name, tablespace_name
from all_tables
where owner = 'SYS'
and tablespace_name is not null;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.