PDA

View Full Version : dynamisches sql mit group by



Seiten : [1] 2

n_sman
04-07-12, 13:20
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

Fuerchau
04-07-12, 13:22
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

Fuerchau
04-07-12, 16:56
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.

Fuerchau
04-07-12, 18:43
Im V5R4-Handbuch ist es noch als "neu" markiert.

n_sman
05-07-12, 07:01
Schaut ja echt gut aus, da werde ich mich gleich mal dranmachen.

Vielen Dank erstmal!

kitvb1
05-07-12, 07:23
Hier ist was ganz einfaches. Schau mal punkt 3.1 an.
http://www.sss-software.de/inn/powerinfo/iNN-PowerInfo0907.pdf

n_sman
09-07-12, 09:22
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-

Fuerchau
09-07-12, 09:32
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.