By Frank Kalis
GETDATE() ist nichtdeterministisch. Eine deterministische Funktion liefert ceteris paribus immer das gleiche Ergebnis. Da GETDATE() keine Argumente entgegennimmt und stets unterschiedliche Werte zurückgibt, ist die Funktion nicht deterministisch. Dies ist auch der Grund, warum man GETDATE() nicht als DEFAULT innerhalb der Funktion definieren kann. Nur deterministische Funktionen können, wie in BOL beschrieben, in UDF's verwendet werden.
Man kann das aber umgehen, indem man einen VIEW erzeugt, der GETDATE() zurückgibt und dann diesen VIEW in der UDF referenziert.
Anmerkung 28.06.2004: Die Verwendung eines Views kann zu inkorrekten Ergebnissen führen. Beispiel:
USE northwind GO CREATE VIEW foolview AS SELECT GETDATE() AS Jetzt GO CREATE FUNCTION fool_me() RETURNS DATETIME AS BEGIN RETURN ( SELECT Jetzt FROM foolview ) END GO CREATE function you_dont_fool_me(@Jetzt datetime) RETURNS DATETIME AS BEGIN RETURN @Jetzt END GO DECLARE @Jetzt datetime SET @Jetzt = GETDATE() --Test 1 viele Zeilen SELECT DISTINCT dbo.fool_me() FROM [Order Details] AS od INNER JOIN Orders AS o ON o.OrderId = od.OrderID --Test2 eine Zeile SELECT DISTINCT dbo.you_dont_fool_me(@Jetzt) FROM [Order Details] AS od INNER JOIN Orders AS o ON o.OrderId = od.OrderID GO DROP FUNCTION fool_me DROP FUNCTION you_dont_fool_me DROP VIEW foolview ------------------------------------------------------ 2004-06-29 10:25:17.320 2004-06-29 10:25:17.330 2004-06-29 10:25:17.240 2004-06-29 10:25:17.270 2004-06-29 10:25:17.280 2004-06-29 10:25:17.300 2004-06-29 10:25:17.330 2004-06-29 10:25:17.250 2004-06-29 10:25:17.260 2004-06-29 10:25:17.280 2004-06-29 10:25:17.290 2004-06-29 10:25:17.310 2004-06-29 10:25:17.320 2004-06-29 10:25:17.230 2004-06-29 10:25:17.240 2004-06-29 10:25:17.260 2004-06-29 10:25:17.270 2004-06-29 10:25:17.290 (18 row(s) affected) ------------------------------------------------------ 2004-06-29 10:25:17.230 (1 row(s) affected)
Was dieses Beispiel auch noch gut demonstriert ist die Tatsache, dass ein UDF für jede Zeile neu kalkuliert wird.
Einfacher ist es, GETDATE() der UDF beim Aufruf mitzugeben wie hier:
CREATE FUNCTION GetDate2 (@getdate DATETIME) RETURNS DATETIME AS BEGIN RETURN (@getdate) END GO SELECT dbo.GetDate2(GETDATE()) AS Jetzt DROP FUNCTION GetDate2 Jetzt ------------------------------------------------------ 2004-06-28 13:11:47.357 (1 row(s) affected)