Anmelden

View Full Version : SQL UDF mit Tabel



Seiten : 1 [2]

Fuerchau
21-01-20, 17:09
Ich habe mir das etwas einfacher gemacht:



-- ERSTELLEN TABELLENFUNKTION ZUM DOWNLOAD DER ABWEICHENDEN NA-GRÜNDE
CREATE OR REPLACE FUNCTION BIUMO220.GETBDELNA
(YYFIRM CHAR(1)
,YYWKNR CHAR(3)
)
RETURNS TABLE (B1FIRM CHAR(1)
,B1WKNR CHAR(3)
,B1AGRF DEC(11, 0)
,B1TXNR CHAR(6)
,B1KOMP CHAR(13)
)
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN
CALL BIUMO220.FUEBDELNA(YYFIRM, YYWKNR);
RETURN SELECT *
FROM BDELNA
WHERE B1FIRM = YYFIRM
AND B1WKNR = YYWKNR;
END;


Die Tabelle wird von mir dann in dem CALL-Programm gefüllt.
An Stelle einer statischen Tabelle kann man auch eine Tabelle in QTEMP verwenden um eine Parallelisierung zu ermöglichen. Hier war das nicht gefordert, da der Zugriff per ODBC erfolgt und alle Daten benötigt werden.

B.Hauser
21-01-20, 17:13
Eine (externe) UDTF wird mindestens 3x Aufgerufen:
- OPEN Call
- FETCH Call
- CLOSE Call

Diese 3 Schritte muss Du Programmieren.
Wobei der FETCH call solange aufgeruen wird bis Du den Status 02000 setzt.
Bei jedem FETCH call gibst Du einen Satz zurück. Dabei spielt es keine Rolle, ob Du den "Satz" aus einer Datenstruktur (die Du beim OPEN gefüllt hast) oder einer Tabelle/View, die du (satzweise) verarbeitest oder aus einem User Space (der z.B. durch ein LIST API) gefüllt wurde, liest.
Habe ich nicht Beispiele zum Verarbeiten einer intern beschriebenen Tabelle bzw. eines List APIs in dem Artikel.

... und Du gibst KEIN Select zurück (das funktioniert nur bei SQL Funktionen!), sondern programmierst eine ganz normale Schleife aus der beim FETCH die Ausgabe-Felder gefüllt werden.

Birgitta

malzusrex
21-01-20, 17:33
@Baldur
Das werde ich mal ausprobieren. Der Gedanke gefällt mir.

@Birgitta
In meinem RPG-Programm habe ich gar keine Verarbeitung einer Datei.
In den Proggi werden diverse Programme aufgerufen, welche dann meine Werte befüllen.

Ich gebe euch dann Bescheid
Danke erst einmal euch Beiden

B.Hauser
21-01-20, 18:07
Ich sehe immer noch das Problem nicht!
Die hast 2 Möglichkeiten:
1. Du rufst Deine Programme beim OPEN auf und füllst eine (Array) Datenstruktur. Diese (Array)-Datenstruktur liest Du dann beim FETCH aus und gibst jeweils die Werte des gelesenen Indices aus.
2. Deine Programme liefern jeweils einen Satz zurück, dann must Du die Programme beim Fetch aufrufen und die zurückgegebenen Werte ausgeben.

Birgitta

malzusrex
21-01-20, 20:00
Liebe Birgitta,

habe ich jetzt in meinen PGM so gemacht
OpenCall = diverse Felder initialisieren
FetchCall = meine Felder füllen und Status auf '0200' setzen
ClosCall = Einfach nur ein Return

Aufruf der Funktion und es kommen keine Daten an..
:-(

Habe es jetzt wie Baldur gemacht. Da bekomme ich meine Daten.
Ist zwar ein Umweg, mit der Ausgabe in eine Zwischendatei, aber es geht erst einmal.

Werde nich aber mit dem Thema noch einmal auseinander setzten.

Schönen Abend noch
Gruß Ronald

B.Hauser
22-01-20, 05:19
Du darfst den Status nicht gleich beim ersten FETCH auf 02000 setzen. Setzt Dir ein Kennzeichen, dass der FETCH bereits ausgeführt wurde und setze dann wenn das Flag gesetzt wurde den Status.


Birgitta

malzusrex
22-01-20, 06:21
Hallo Birgitta!

Das war es!
Jetzt macht er auch das, was ich will.

Vielen Dank für den Tipp
Gruß
Ronald

Fuerchau
22-01-20, 09:39
Das ist genauso wie beim klassischen READ.
%EOF wird erst nach dem Read gemeldet, wenn keine Daten gelesen wurden.
So verhält es sich nun auch mit dem Status 02000.

Meine Lösung mit der Zwischentabelle war auch deshalb erforderlich um DISTINCT-Daten zu erstellen (Unique Key Constraint).
Wenn DISTINCT aber erst nach dem Bereitstellen abgefragt wird, dauert das Ganze eben länger, da man ja nicht auf bereits returnierte Daten zugreifen kann.
Kommt halt immer darauf an, was man gerade benötigt.

malzusrex
22-01-20, 09:46
Ich habe jetzt beide Varianten umgesetzt.

Danke euch Beiden noch einmal

Gruß
Ronald