首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 函數中巧用 GETDATE():繞過「非確定性函數」限制的實戰技巧

     編輯:關於SqlServer

在 SQL Server 使用者定義函數(UDF)中直接呼叫 GETDATE() 會報錯,因為它屬於「非確定性函數」(Non-deterministic Function)——相同輸入可能產生不同輸出,且會產生副作用。官方文件明確列出 GETDATE、RAND、NEWID 等函數禁止在 UDF 主體中使用。

核心解法:透過 View 間接取得系統時間

利用「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();

原理解析

  • 確定性 vs 非確定性:確定性函數相同輸入必得相同結果;非確定性函數(如 GETDATE、RAND)每次呼叫結果不同,且可能修改全域狀態(副作用)。
  • 限制原因:UDF 設計為無副作用、可內嵌查詢計畫,引入非確定性函數會破壞最佳化器假設,導致結果不可預期。
  • View 例外:View 定義本質是預儲存的查詢,執行時才展開,允許參考非確定性函數,因此成為合法的「橋樑」。

擴充應用:取得 UTC 時間或其他系統函數

同理可建立 v_getutcdate、v_newid 等 View,再封裝為函數,滿足各類「在 UDF 中取得系統動態值」的需求。

注意事項

  • 此技巧僅適用於 SQL Server 2000/2005/2008 等舊版本;新版本(2012+)已支援 SYSDATETIME() 等更高精度函數,但限制邏輯相同。
  • 若頻繁在大量查詢中呼叫此函數,效能較直接內嵌 GETDATE() 稍低,建議視情境評估。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved