CSV genereren vanuit Invantive Cloud en UniversalSQL

Met Invantive UniversalSQL kunnen CSV-files omgezet worden via een select op een csvtable, zoals bijvoorbeeld beschreven in Relate Nationale Ombudsman Statistics with CBS.

De andere richting - namelijk het omzetten van resultaten uit een query in CSV - is ook mogelijk vanaf versie 22.0.16. De werking is vergelijkbaar met het omzetten naar XML en JSON met, respectievelijk, for xml en for json (voorbeeld). Ook het omzetten naar Excel-file is mogelijk zoals beschreven in Excel genereren vanuit Invantive Cloud en UniversalSQL.

De for csv clause

Het omzetten van de resultaten van een select SQL query naar CSV gebeurt door een for csv clause toe te voegen aan het einde van de query. Deze for csv clause zorgt er voor dat de query maar één kolom teruggeeft met in de waarde van CSV de volledige resultaten van het select-statement bevat als CSV. Het aantal rijen is afhankelijk van de hoeveelheid data en wordt gepagineerd per 1.000 rijen (standaard, instelbaar via output per ... rows).

Via extra mogelijkheden op de for csv clause kan het uitvoerformaat gepreciseerd worden:

Standaard wordt gewerkt met per regel een record, en de kolommen gescheiden door comma’s. Het escapekarakter is het dubbele aanhalingsteken, dat binnen een tekst geescaped wordt met een backslash.

CSV uitvoer SQL voorbeeld met path

Met de volgende query op de dual voorbeeldtabel wordt CSV gegenereerd:

select rge1.value value1
,      rge2.value value2
from   range(10)@DataDictionary rge1
join   range(10)@DataDictionary rge2
for    csv

Het resultaat is:

value1,value2
1,1
1,2
1,3
...

CSV-uitvoerformaat configureren

Zoals beschreven in de Invantive UniversalSQL-grammatica kan de uitvoer geconfigureerd worden.

Door gebruik van INCLUDE HEADERS en EXCLUDE HEADERS kan de eerste regel met de kolomkoppen toegevoegd (standaard) of achterwege gelaten worden zoals met:

select rge1.value value1
,      rge2.value value2
from   range(10)@DataDictionary rge1
join   range(10)@DataDictionary rge2
for    csv
,      exclude headers

De kolomscheider, rijscheider en de escapekarakters kunnen ook ingesteld worden. Maar ook het aantal rijen dat gecombineerd wordt in een uitvoerrij (standaard 1.000). Tenslotte kan per uitvoerrij een kop toegevoegd worden.

Een voorbeeld dat al deze mogelijkheden laat zien is:

select rge1.value value1
,      rge2.value value2
from   range(10)@DataDictionary rge1
join   range(10)@DataDictionary rge2
for    csv
,      include headers
,      row delimiter '#'
,      column delimiter '-'
,      quoting character ''
,      escaped quoting character ''
,      output per 3 rows repeat headers

met als resultaat:

value1-value2#1-1#1-2#1-3
value1-value2#1-4#1-5#1-6
value1-value2#1-7#1-8#1-9
...

CSV uitvoer van webpagina’s op app-online

De CSV die als uitvoer uit een query met for csv clause komt is eenvoudig terug te geven via een applicatiemodule op Invantive Cloud. Dat kan voor grootschalig gebruik ook via app-online. Vergeet in dat geval niet om het Content Type van de gegenereerde pagina in te stellen op application/csv. Op deze wijze kunnen eenvoudig rapporten gemaakt worden die met enkele of meerdere queries CSV teruggeven voor verdere verwerking in andere pakketten of EDI.

Geheugenbeslag for csv

De for csv clause geeft één of meerdere rijen terug, afhankelijk van de hoeveelheid data en gepagineerd zoals boven beschreven.

Bij gebruik van listagg in Invantive UniversalSQL kunnen de gegevens samengevoegd worden, mits de CSV niet langer wordt dan 2 GB of te wel 1 miljard tekens (in UTF16). In dat geval dient de software die de Invantive UniversalSQL aanroept zelf in brokken de gegevens samen te voegen tot één grote tekst.

Select csv kolom

De for csv achter de query verandert het aantal kolommen die uit de query terugkomen. Alle kolommen van de query verdwijnen en worden vervangen door de kolom csv die de uitkomst van een groepfunctie op de opgevraagde waarden is. Echter, dit gebeurt pas na het selecteren van de kolommen met select * of select COLUMNS.

Alhoewel het logisch is dat de for csv gebeurt na het selecteren van de op te nemen kolommen, kan het verwarrend zijn. Een query zoals:

select csv csv_new
from   dual@datadictionary
for    csv

is niet mogelijk omdat de csv kolom al de oorspronkelijke kolommen vervangt na de selectie. Als de kolomnaam absoluut ingesteld moet worden, gebruik dan een constructie zoals:

select csv csv_new
from   ( select *
         from dual@datadictionary
         for    csv
       )