GETDATE innerhalb einer UDF

By Frank Kalis

Posted on Jul 12, 2004 von in SQL Server

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)
Tags: Tags:
Dieser Eintrag wurde eingetragen von und ist abgelegt unter SQL Server. Tags: , ,

Noch kein Feedback


Formular wird geladen...