PDA

View Full Version : Erstellen einer UDF mit UNION



e_sichert
09-05-08, 08:35
Hallo zusammen,

ich möchte eine UDF erstellen die folgendermaßen aussieht.

CREATE FUNCTION TSIMOS.UDF2 (
ARTIKELNR VARCHAR(20))
RETURNS TABLE (
AstNum VARCHAR(20) ,
BucSts VARCHAR(1))
LANGUAGE SQL
SPECIFIC TSIMOS.UDF2
NOT DETERMINISTIC
READS SQL DATA
CALLED ON NULL INPUT
DISALLOW PARALLEL
BEGIN
RETURN
Select K.AstNum,K.BucSts
From FSBD102FAS.FSKRE01P K
Join FSBD101FAS.FSAST00P A
ON K.AstNum = A.AstNum
Where K.AstNum = ArtikelNr

UNION ALL

Select F.AstNum,F.BucSts
From FSBD102FAS.FSFRE00P F
Join FSBD101FAS.FSAST00P X
ON F.AstNum = X.AstNum
Where F.AstNum = ArtikelNr;
END

In den Primärtabellen FSBD102FAS.FSKRE01P und FSBD102FAS.FSFRE00P existiert jeweils ein Feld Namens AstNum.

Nun das Problem:
Wenn ich die UDF mit einem Select Statement erstelle funktioniert das.
Wenn ich die UDF mit den beiden Select Statements erstelle (mit dem UNION ALL) und jeweils die Sekundärdatei weglasse funktioniert das auch.
Wenn ich aber die UDF wie oben abgebildet erstellen will kommt der Fehler:
SQL-Status: 42702
Vendorencode: -203
Nachricht: [SQL0203] Name ASTNUM ist nicht eindeutig.

Ich habe doch für jede Datei ein Präfix vergeben damit die Eindeutigkeit gegeben ist.

Auf was muss ich da noch achten?

Vorab, schon mal vielen Dank für die Hilfe.

BenderD
09-05-08, 09:29
warum denn so kompliziert? das braucht doch keine UDF!!! das geht mit einem nackten SQL Statement

D*B

Programmieren ist ein Handwerk, die Kunst besteht allenfalls darin einfache Lösungen zu suchen!

e_sichert
09-05-08, 09:42
Danke für die Antwort,

vielleicht zum Hintergrund.

Ich möchte die UDF von einem Client Programm aufrufen und die komplette Tabelle zurückerhalten.

... oder gäbe es dazu eine andere Alternative?

BenderD
09-05-08, 10:51
bei den Clients, die ich kenne wäre das dann ein ResultSet, das ich mit einem SELECT ebenfalls bekäme...

D*B


Danke für die Antwort,

vielleicht zum Hintergrund.

Ich möchte die UDF von einem Client Programm aufrufen und die komplette Tabelle zurückerhalten.

... oder gäbe es dazu eine andere Alternative?

e_sichert
09-05-08, 11:03
ja, ich könnte den Select auch vom Clientprogramm (VS2005 und C#) schicken aber ich habe im "LIVE" Select 5 einzelne Select's mit UNION verknüpft von denen jeder nochmal mit 3 Dateien per join verbunden ist und ich verspreche mir beim Aufruf einer UDF einfach einen Performance Gewinn.
Ich habe das gleiche auch schon mit einem MS SQL Server gemacht und da ist der Performancegewinn erheblich.

BenderD
09-05-08, 12:32
da wäre eine View auch noch eine Option, aber ich will dir ja die UDF nicht ausreden. Gebe doch mal den Spalten Namen (select f.astnum astnum, ....)

D*B


ja, ich könnte den Select auch vom Clientprogramm (VS2005 und C#) schicken aber ich habe im "LIVE" Select 5 einzelne Select's mit UNION verknüpft von denen jeder nochmal mit 3 Dateien per join verbunden ist und ich verspreche mir beim Aufruf einer UDF einfach einen Performance Gewinn.
Ich habe das gleiche auch schon mit einem MS SQL Server gemacht und da ist der Performancegewinn erheblich.

Fuerchau
09-05-08, 13:11
Das mag für den SQL-Server ja noch gelten, aber dies gilt nicht mehr für die AS/400.
Egal ob UDF/Procedure oder direktes SQL, der Optimizer schlägt immer gleich zu.
Zumal du mit DISALLOW PARALLEL ja auch noch Performanceeinschränkungen definierst.

Mach lieber, wie Dieter vorgeschlagen hat , eine View und geh direkt mit SQL dran.

Wenn ich mir deinen Join so ansehe, dann benötigst du ja keine Felder aus dem Join.
In diesem Fall arbeite lieber mit:

where ... exists ...

e_sichert
09-05-08, 13:16
Das hatte ich schon probiert - funktioniert auch nicht.

Das seltsame daran ist das die beiden Select's mit dem UNION außerhalb der UDF einwandfrei funktionieren.

Wenn ich in der UDF Definition vom zweiten Select Statement die Sekundärdatei weg nehme funktioniert die UDF Erstellung.

Wenn bei der UDF Erstellung der Fehler auftritt (so wie im obigen Beispiel) springt der Cursor auf das erste Feld (F.AstNum) des zweiten Selects.

file:///C:/DOKUME%7E1/Sichert1/LOKALE%7E1/Temp/moz-screenshot.jpg

Fuerchau
09-05-08, 13:19
Möglicherweise musst du in einer UDF die Ergebnisfelder benennen:

Select F.AstNum as AstNum, F.BucSts as BucSts ...

mit temporären Namen kommt eine UDF ggf. nicht zurecht.

e_sichert
09-05-08, 13:25
Das mag für den SQL-Server ja noch gelten, aber dies gilt nicht mehr für die AS/400.
Egal ob UDF/Procedure oder direktes SQL, der Optimizer schlägt immer gleich zu.
Zumal du mit DISALLOW PARALLEL ja auch noch Performanceeinschränkungen definierst.

Mach lieber, wie Dieter vorgeschlagen hat , eine View und geh direkt mit SQL dran.

Wenn ich mir deinen Join so ansehe, dann benötigst du ja keine Felder aus dem Join.
In diesem Fall arbeite lieber mit:

where ... exists ...

Hallo Ferchau
In meinem richtigen Statement brauche ich schon mehr Felder aus der verbundenen Datei. Ich habe das nur für die Anfrage gekürzt.

Ich denke ich probiere das jetzt doch mal mit einer View.