Je veux extraire certaines requêtes vers un format de sortie CSV. Malheureusement, je ne peux pas utiliser un client SQL fantaisiste ou un langage quelconque pour le faire. Je dois utiliser SQLPLUS.
Comment dois-je m'y prendre ?
Je veux extraire certaines requêtes vers un format de sortie CSV. Malheureusement, je ne peux pas utiliser un client SQL fantaisiste ou un langage quelconque pour le faire. Je dois utiliser SQLPLUS.
Comment dois-je m'y prendre ?
Vous pouvez également utiliser la méthode suivante, bien qu'elle introduise des espaces entre les champs.
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 sortie sera comme :
TABLE_PRIVILEGE_MAP ,SYSTEM
SYSTEM_PRIVILEGE_MAP ,SYSTEM
STMT_AUDIT_OPTION_MAP ,SYSTEM
DUAL ,SYSTEM
...
Ce serait beaucoup moins fastidieux que de taper tous les champs et de les concaténer avec les virgules. Vous pourriez poursuivre avec un simple sed script pour supprimer les espaces blancs qui apparaissent avant une virgule, si vous le souhaitez.
Quelque chose comme ceci pourrait fonctionner...(mes compétences en matière de séduction sont très rouillées, donc il faudra probablement y travailler)
sed 's/\s+,/,/' myfile.csv
Le "," est manquant dans la ligne de colsep. De même, headsep off et linesize X sont susceptibles d'être utiles. Editez la réponse et je l'accepterai.
Merci pour les commentaires, Daniel. L'option "set linesize" est certainement utile, et je l'ai utilisée dans le passé pour ce genre de choses.
La commande sed est : cat monfichier.csv | sed -e 's/[ \t ]*|/|/g ; s/|[ ]*/|/g' > monfichier.csv. Quoi qu'il en soit, Oracle est vraiment nul.
J'utilise cette commande pour les scripts qui extraient des données pour les tables dimensionnelles (DW). J'utilise donc la syntaxe suivante :
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
Et ça marche. Je n'utilise pas sed pour formater le fichier de sortie.
Je vois un problème similaire...
J'ai besoin de spooler un fichier CSV à partir de SQLPLUS, mais la sortie a 250 colonnes.
Ce que j'ai fait pour éviter le formatage ennuyeux de la sortie de 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
le problème est que vous perdrez les noms des en-têtes de colonnes...
vous pouvez ajouter ceci :
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
Je sais que c'est un peu hardcore, mais ça marche pour moi...
Avons-nous besoin ||
pour les sous-requêtes aussi ? je ne pense pas que ce soit nécessaire pour les sous-requêtes. mais oui c'est nécessaire pour la sélection primaire.
Vous pouvez formater explicitement la requête pour produire une chaîne de caractères délimitée avec quelque chose du genre :
select '"'||foo||'","'||bar||'"'
from tab
Et configurez les options de sortie comme il convient. En option, la variable COLSEP de SQLPlus vous permettra de produire des fichiers délimités sans avoir à générer explicitement une chaîne avec les champs concaténés ensemble. Cependant, vous devrez mettre des guillemets autour des chaînes sur toutes les colonnes qui pourraient contenir des caractères de virgule incorporés.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.