Як я можу створити файл у форматі CSV за допомогою SQLPLUS?


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 's/\s+,/,/' myfile.csv 

У рядку "colsep" відсутнє ",". Також, ймовірно, будуть корисні вимикання гарнітури та розмір X. Відредагуйте відповідь, і я прийму її.
Даніель К. Собрал

5
Команда sed є: cat myfile.csv | sed -e 's / [\ t] * | / | / г; s / | [] * / | / g '> myfile.csv. У будь-якому випадку Oracle дійсно смокче.
Стен

2
А щоб отримати заголовок з іменами стовпців використовувати set pagesize 1000замість 0. У моєму попередньому коментарі, ви не можете перенаправити в той же файл: cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv.
Стен

1
Я відфільтрував заготовки та тире, які використовувались для того, щоб підкреслити grepі trподібне grep -v -- ----- myfile.csv | tr -d [:blank:] > myfile.csv.
ixe013

1
@slayernoah команда spool може взяти шлях до каталогу та ім'я файлу, так що ви можете точно вказати, де саме буде розміщений вихідний файл. Інакше це залежатиме від місця, де ви виконуєте сценарій.
Гейб

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

Я бачу подібну проблему ...

Мені потрібно згорнути CSV-файл із SQLPLUS, але вихід має 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 ... тощо. там потрібно.
Аміт Найду

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>
  • Версія для розробників SQL до 4.1

Крім того, ви можете використовувати новий підказку в SQL Developer ./*csv*/

/*csv*/

Наприклад, у моїй версії 3.2.20.10 для розробника SQL :

введіть тут опис зображення

Тепер ви можете зберегти вихід у файл.

  • Версія 4.1 для розробника SQL

Нове у версії 4.1 для SQL Developer, використовуйте наступне, як команду 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;

Гарний вилов на підкресленому варіанті, потрібен саме той.
ноккандо

Приємно, якщо ви хочете 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

І встановіть параметри виводу, як це підходить. Як варіант, змінна COLSEP на SQLPlus дозволить вам створювати файли з розмежуванням без необхідності явно генерувати рядок із з’єднаними разом полями. Однак вам доведеться ставити лапки навколо рядків на будь-яких стовпцях, які можуть містити вбудовані символи комами.


4

вважають за краще використовувати "set colsep" у запиті sqlplus, а не редагувати назву col по одному. Використовуйте sed для редагування вихідного файлу.

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


2

Ви повинні знати, що значення полів можуть містити коми та цитати, тому деякі із запропонованих відповідей не спрацюють, оскільки вихідний файл CSV був би невірним. Щоб замінити символи котирування в полі та замінити його символом подвійної лапки, ви можете скористатися функцією ЗАМІНИ, яку надає oracle, щоб змінити одну пропозицію на подвійну.

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()зайве.
Аміт Найду

1

Використовуйте vi або vim для написання sql, використовуйте colsep з контролем-A (in vi і vim передують ctrl-A з ctrl-v). Не забудьте встановити розмір рядків і розмірів сторінок на щось раціональне і включити trimspool та обробку.

відкрутіть його у файл. Тоді...

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

Цю річ седу можна перетворити на сценарій. "*" До і після ctrl-A видаляє всі непотрібні пробіли. Хіба це не здорово, що вони турбуються, щоб увімкнути HTML-вихід із sqlplus, але НЕ рідного csv ?????

Я роблю це таким чином, оскільки він обробляє коми в даних. Я перетворюю їх на напівколони.


3
Це не вдається тесту "я повинен використовувати SQLPlus".
Даніель К. Собрал

0

Виникла проблема використання sqlplus для створення CSV-файлів. Якщо ви хочете, щоб заголовки стовпців були лише один раз у виході, і вони є тисячами або мільйонами рядків, ви не можете встановити розмір сторінок досить великий, щоб не повторитись. Рішення полягає в тому, щоб почати з pagesize = 50 і проаналізувати заголовки, а потім знову надіслати виділення з sizeize = 0, щоб отримати дані. Дивіться скрипт 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

Я написав цей чисто сценарій SQLPlus, щоб скинути таблиці в CSV в 1994 році.

Як зазначається в коментарях до сценарію, хтось із 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.