SQL Server Scalar Valued Functions über T SQL aufrufen

22/11/2008 - 12:55 von Akiono Wan | Report spam
Hallo, ich habe folgendes Problem:

Ich habe 2 Functions: GetAge(@Birthdate Datetime) und GetValue(@Age
Int)

Ich möchte jetzt mit T-SQL eine Abfrage bauen, bei der der
Rückgabewert von GetAge() in GetValue() genutzt werden kann. Dabei
möchte ich den Datensatz nur einmal anpacken und die Funktion GetAge
auch nur einmal aufrufen. Kurz gefasst, ich muss das Alter
zwischenspeichern.

Ansatz war folgender:

select Name, dbo.GetAge(GEB_DATUM) as Alter, dbo.GetValue(Alter) as
Wert into Kunden from People

Hier schmeisst er mir die Exception, dass er die Spalte Alter nicht
kennt.

Daher benötige ich einen Mechanismus, um das Alter in eine temporàre
Variable zwischenzuspeichern.

Was ich nicht möchte ist:
doppelter Aufruf:
select Name, dbo.GetAge(GEB_DATUM) as Alter, dbo.GetValue(dbo.GetAge
(GEB_DATUM)) as Wert into Kunden from People

da die Functionen nur Beispiele sind und meine echten Functionen
wesentlich zeitaufwàndiger zu berechnen sind.

Wenn man es mit einer Stored Procedure umzusetzen kann, ist das auch
ok. Ich möchte aber, das jeder Datensatz nur einmal angefasst wird, da
es sich hier auch um Millionen von Datensàtzen handelt.

Vielen Dank für Ansàtze und Tipps.

Gruss
Akiono
 

Lesen sie die antworten

#1 Elmar Boye
22/11/2008 - 17:33 | Warnen spam
Hallo Akiono,

"Akiono Wan" schrieb ...
Ich habe 2 Functions: GetAge(@Birthdate Datetime)
und GetValue(@Age Int)

Ich möchte jetzt mit T-SQL eine Abfrage bauen, bei der der
Rückgabewert von GetAge() in GetValue() genutzt werden kann. Dabei
möchte ich den Datensatz nur einmal anpacken und die Funktion GetAge
auch nur einmal aufrufen. Kurz gefasst, ich muss das Alter
zwischenspeichern.

Ansatz war folgender:

select Name, dbo.GetAge(GEB_DATUM) as Alter, dbo.GetValue(Alter) as
Wert into Kunden from People



Das geht grundsàtzlich nicht, da ein Spaltenalias wie hier "Alter"
nur für die Ausgabe relevant ist und erst in ORDER BY definiert ist.

Was ich nicht möchte ist:
doppelter Aufruf:

select Name, dbo.GetAge(GEB_DATUM) as Alter, dbo.GetValue(dbo.GetAge
(GEB_DATUM)) as Wert into Kunden from People



Um das zu vermeiden, kannst Du eine abgeleitete Tabelle verwenden:

SELECT d.Name, d.Alter, dbo.GetValue(d.Alter) AS Wert
INTO dbo.Kunden
FROM (SELECT Name,
dbo.GetAge(GEB_DATUM) AS Alter
FROM People) AS d

da die Functionen nur Beispiele sind und meine echten Functionen
wesentlich zeitaufwàndiger zu berechnen sind.
Ich möchte aber, das jeder Datensatz nur einmal angefasst wird, da
es sich hier auch um Millionen von Datensàtzen handelt.



Skalare Funktionen sind eher langsam, da sie vom Optimierer
nicht in die Abfrage integriert werden können.
Und bei großen Datenmegen sollte man sie eher meiden.
Besser wàre eine Implementation z. B. als CTE.

Gruß Elmar

Ähnliche fragen