View Full Version : dynamisches sql mit group by
Hallo,
ich sollte eine sehr umfangreiche tabell nach frei wählbaren Feldern verdichten.
Rein logisch funktioniert das mit folgendem Statement
select feld1, feld2, feld3, sum(wert1), sum(wert2)
from tabelle
group by feld1, feld2, feld3
Es ist aber so, dass es verschiedene Felder in verschiedender Anzahl sein können.
Ein SelectStatement zu erzeugen ist kein Problem, aber wie kann ich einen Satz mit einer variierender Anzahl von Feldern "fetchen"? - hier muss ja normalerweise die genaue anzahl der Fehlder angegeben werden.
danke schonmal
gruss
ennsman
Das ist dann schon etwas komplizierter.
Hierfür musst du SQLDA-Tabellen anlegen, mit Pointern arbeiten, "describe statement" aufrufen und beim Fetch dann "...using sqlda..." verwenden.
andreaspr@aon.at
04-07-12, 15:37
... viel zu kompliziert eigentlich ...
Meiner Meinung geht das am "einfachsten" mit dem SQL Descriptor.
Ich hab mir da mal ein Beispiel-PGM zusammen gebastelt. Leider gibts darüber nicht viel Dokus bei der IBM.
Aber so sollte es klappen :):
D vsql s 512
D vtype s 10
D vlength s 10 0
D vresult_ind s 10 0
D vCount S 10 0
D i S 10 0
/Free
//---- Sql Optionen setzen ----
Exec Sql SET OPTION COMMIT=*NONE, CLOSQLCSR=*ENDMOD,
ALWBLK=*ALLREAD, ALWCPYDTA=*YES,
SRTSEQ=*HEX, DLYPRP=*YES;
// SQL Cursor erstellen
vSql = 'Select * From tab1';
Exec Sql Prepare S1 from :vsql;
Exec Sql Declare c1 Cursor For s1;
// Descriptor mit der max. Anzahl der Spalten initialisieren
Exec Sql allocate descriptor 'mydesc' with max 2;
EXEC SQL DESCRIBE S1 Using descriptor 'mydesc';
// Ersten Satz einlesen
Exec Sql open c1;
Exec Sql Fetch c1 into sql descriptor 'mydesc';
// Anzahl der Spalten abrufen
EXEC SQL GET DESCRIPTOR 'mydesc' :vCount = COUNT;
// Alle Spalten mit deren Werte einlesen
For i=0 to vCount;
// Attribute der Spalte einlesen
Exec Sql GET DESCRIPTOR 'mydesc' VALUE :i
:vtype = TYPE,
:vlength = LENGTH,
:vresult_ind = INDICATOR;
if vresult_ind >= 0;
Select;
When vtype = '1'; // Character
exec Sql GET DESCRIPTOR 'mydesc' VALUE :i
:sp2 = DATA;
When vtype = '4'; // Integer
exec Sql GET DESCRIPTOR 'mydesc' VALUE :i
:sp1 = DATA;
endsl;
endif;
endfor;
Exec Sql close c1;
*INLR = *ON;
/End-Free
Das vereinfacht die Sache natürlich nicht unerheblich.
Ab welchem Release ist das denn dazu gekommen?
Mit SQLDA's arbeite ich seit V4R3, aber man kann ja nicht alles kennen.
Allerdings benötigt man da ja erheblich mehr SQL-Aufrufe so dass SQLDA's, wenn auch komplzierter, dann doch wohl schneller sind (1 Fetch = alle Felder).
andreaspr@aon.at
04-07-12, 18:40
Ab welchem Release ist das denn dazu gekommen?
Kann ich jetzt gar nicht genau sagen. Ab V5R4 gehts auf jeden Fall. Eventuell auch bei V5R3? Schätze, dass es das viel früher nicht gab.
Im V5R4-Handbuch ist es noch als "neu" markiert.
Schaut ja echt gut aus, da werde ich mich gleich mal dranmachen.
Vielen Dank erstmal!
Hier ist was ganz einfaches. Schau mal punkt 3.1 an.
http://www.sss-software.de/inn/powerinfo/iNN-PowerInfo0907.pdf
Das mit den Descriptoren habe ich schonmal hinbekommen, leider funktioniert das auslesen für numerische Werte nicht - ich empfange nur alpha-Werte.
Als Datentype erhalte ich '3', wenn ich diesen Wert in ein Feld mit gleichem Typ wie das DB-Feld schiebe erhalte ich SQLError -076 (Datentypen nicht gleich)
Ich weiss das ist eine Frage die schon sehr ins Detail, habe aber nichts mehr darüber gefunden.
Danke
ennsman-
Je Datentyp solltest du halt unterschiedliche Zielfelder angeben.
Bei numerisch nimm halt Zoned(31,9), bei gepackt packed(31,9).
ANsonsten musst du deinen SQL für jedes Feld einen "CHAR(Field)" verwenden, dann castet SQL selber.