在 SQL Server 使用者定義函數(UDF)中直接呼叫 GETDATE() 會報錯,因為它屬於「非確定性函數」(Non-deterministic Function)——相同輸入可能產生不同輸出,且會產生副作用。官方文件明確列出 GETDATE、RAND、NEWID 等函數禁止在 UDF 主體中使用。
利用「View 可包含非確定性函數」的特性,建立一個回傳 GETDATE() 的檢視表,再在函數中查詢該 View,即可合法取得目前日期時間。
-- 1. 建立檢視表,封裝 GETDATE()
CREATE VIEW v_getdate
AS
SELECT GETDATE() AS [output];
GO
-- 2. 建立標量函數,透過 View 取得時間
CREATE FUNCTION f_getdate()
RETURNS DATETIME
AS
BEGIN
DECLARE @n DATETIME;
SELECT @n = [output] FROM v_getdate;
RETURN @n;
END;
GO
-- 3. 呼叫測試
SELECT dbo.f_getdate();
GETDATE、RAND)每次呼叫結果不同,且可能修改全域狀態(副作用)。同理可建立 v_getutcdate、v_newid 等 View,再封裝為函數,滿足各類「在 UDF 中取得系統動態值」的需求。
SYSDATETIME() 等更高精度函數,但限制邏輯相同。GETDATE() 稍低,建議視情境評估。