Quiero extraer algunas consultas a un formato de salida CSV. Desafortunadamente, no puedo usar ningún cliente SQL sofisticado ni ningún idioma para hacerlo. Debo usar SQLPLUS.
¿Cómo lo hago?
Quiero extraer algunas consultas a un formato de salida CSV. Desafortunadamente, no puedo usar ningún cliente SQL sofisticado ni ningún idioma para hacerlo. Debo usar SQLPLUS.
¿Cómo lo hago?
Respuestas:
Si está utilizando 12.2, simplemente puede decir
set markup csv on
spool myfile.csv
También podría usar lo siguiente, aunque introduce espacios entre campos.
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;
La salida será como:
TABLE_PRIVILEGE_MAP ,SYSTEM
SYSTEM_PRIVILEGE_MAP ,SYSTEM
STMT_AUDIT_OPTION_MAP ,SYSTEM
DUAL ,SYSTEM
...
Esto sería mucho menos tedioso que escribir todos los campos y concatenarlos con las comas. Si lo desea, puede seguir con un script sed simple para eliminar los espacios en blanco que aparecen antes de una coma.
Algo como esto podría funcionar ... (mis habilidades sed están muy oxidadas, por lo que es probable que esto necesite trabajo)
sed 's/\s+,/,/' myfile.csv
set pagesize 1000
en lugar de 0. En mi comentario anterior, no se puede redirigir en el mismo archivo: cat myfile.csv | sed -e 's/[ \t]*|/|/g ; s/|[ ]*/|/g' > my_other_file.csv
.
grep
y tr
así grep -v -- ----- myfile.csv | tr -d [:blank:] > myfile.csv
.
Uso este comando para scripts que extraen datos para tablas dimensionales (DW). Entonces, uso la siguiente sintaxis:
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
Y funciona. No uso sed para formatear el archivo de salida.
Veo un problema similar ...
Necesito poner en cola el archivo CSV de SQLPLUS, pero el resultado tiene 250 columnas.
Lo que hice para evitar el molesto formato de salida 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
el problema es que perderá los nombres de encabezado de columna ...
puedes agregar esto:
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
Sé que es un poco duro, pero funciona para mí ...
||
también subconsultas ?, no creo que sea necesario para las subconsultas. pero sí, se requiere para la selección primaria.
select x
? Esto debería funcionar sin él. @davidb, tiene razón en que la concatenación no es necesaria en la subconsulta interna primaria, pero alias todas las columnas como col1, col2 ... etc. Se requiere allí.
Con las versiones más recientes de las herramientas del cliente, existen múltiples opciones para formatear el resultado de la consulta. El resto es ponerlo en cola en un archivo o guardar la salida como un archivo dependiendo de la herramienta del cliente. Estas son algunas de las formas:
Usando los comandos SQL * Plus, puede formatear para obtener el resultado deseado. Use SPOOL para poner en cola la salida a un archivo.
Por ejemplo,
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>
Alternativamente, puede usar la nueva pista en SQL Developer ./*csv*/
/*csv*/
Por ejemplo, en mi SQL Developer Versión 3.2.20.10 :
Ahora podría guardar la salida en un archivo.
Nuevo en SQL Developer versión 4.1, use lo siguiente al igual que el comando sqlplus y ejecútelo como script. No es necesario la pista en la consulta.
SET SQLFORMAT csv
Ahora podría guardar la salida en un archivo.
Sé que este es un hilo antiguo, sin embargo, noté que nadie mencionó la opción de subrayado, que puede eliminar los subrayados debajo de los encabezados de las columnas.
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;
Es crudo, pero:
set pagesize 0 linesize 500 trimspool on feedback off echo off
select '"' || empno || '","' || ename || '","' || deptno || '"' as text
from emp
spool emp.csv
/
spool off
Puede formatear explícitamente la consulta para producir una cadena delimitada con algo similar a:
select '"'||foo||'","'||bar||'"'
from tab
Y configure las opciones de salida según corresponda. Como opción, la variable COLSEP en SQLPlus le permitirá producir archivos delimitados sin tener que generar explícitamente una cadena con los campos concatenados juntos. Sin embargo, tendrá que poner comillas alrededor de las cadenas en cualquier columna que pueda contener caracteres de coma incrustados.
Una vez escribí un pequeño script SQL * Plus que usa dbms_sql
y dbms_output
para crear un csv (en realidad un ssv). Puedes encontrarlo en mi repositorio Githup .
Debe tener en cuenta que los valores de los campos pueden contener comas y caracteres de comillas, por lo que algunas de las respuestas sugeridas no funcionarían, ya que el archivo de salida CSV no sería correcto. Para reemplazar los caracteres de comillas en un campo y reemplazarlos con el carácter de comillas dobles, puede usar la función REEMPLAZAR que proporciona Oracle, para cambiar una comilla simple a comilla doble.
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
O, si desea el carácter de comillas simples para los campos:
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()
es innecesario.
Use vi o vim para escribir el sql, use colsep con un control-A (en vi y vim preceden el ctrl-A con un ctrl-v). Asegúrese de establecer el tamaño de línea y el tamaño de página en algo racional y active el trimspool y el recorte.
ponerlo en cola en un archivo. Luego...
sed -e 's/,/;/g' -e 's/ *{ctrl-a} */,/g' {spooled file} > output.csv
Esa cosa sed puede convertirse en un guión. El "*" antes y después del ctrl-A exprime todos los espacios inútiles. ¿No es genial que se hayan molestado en habilitar la salida html de sqlplus pero NO en el csv nativo?
Lo hago de esta manera porque maneja comas en los datos. Los convierto en punto y coma.
Hay un problema al usar sqlplus para crear archivos csv. Si desea los encabezados de columna solo una vez en la salida y hay miles o millones de filas, no puede establecer un tamaño de página lo suficientemente grande como para no repetir. La solución es comenzar con pagesize = 50 y analizar los encabezados, luego emitir la selección nuevamente con pagesize = 0 para obtener los datos. Ver script bash a continuació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
}
Escribí este script puramente SQLPlus para volcar tablas a CSV en 1994.
Como se señaló en los comentarios del script, alguien en Oracle puso mi script en una nota de Soporte de Oracle, pero sin atribución.
https://github.com/jkstill/oracle-script-lib/blob/master/sql/dump.sql
El script también crea un archivo de control y un archivo de parámetros para SQL * LOADER
spool D:\test.txt
select * from emp
spool off
Puede usar la sugerencia csv. Vea el siguiente ejemplo:
select /*csv*/ table_name, tablespace_name
from all_tables
where owner = 'SYS'
and tablespace_name is not null;