共用方式為


決定性和非決定性函式

每當使用一組特定的輸入值呼叫時,具決定性函數一律會傳回相同的結果,並指定資料庫相同的狀態。 即使存取的資料庫狀態保持不變,非決定性函式每次使用一組特定的輸入值呼叫時,都可能會傳回不同的結果。 例如,根據上述限定性,AVG 函式一律會傳回相同的結果,但傳回目前日期時間值的 GETDATE 函式一律會傳回不同的結果。

使用者定義函式有數個屬性,可決定 SQL Server Database Engine 能夠透過呼叫函式的計算數據行索引,或透過參考函式的索引檢視來編製函數結果的索引。 函式的決定性是一個這類屬性。 例如,如果檢視參考任何非決定性函式,則無法在檢視上建立叢集索引。 如需函式屬性的詳細資訊,包括決定性,請參閱 函式User-Defined

本主題會識別內建系統函式的決定性,以及在包含擴充預存程式呼叫時,對使用者定義函數的決定性屬性的影響。

內建函式確定性

您無法影響任何內建函式的決定性。 每個內建函式都是根據 SQL Server 如何實作函式而具決定性或不具決定性的。 例如,在查詢中指定 ORDER BY 子句並不會變更該查詢中使用的函式決定性。

所有字串內建函式都是具決定性的。 如需這些函式的清單,請參閱字串函式 (Transact-SQL)。

下列來自字串函式以外的內建函式類別的內建函式一律具決定性。

ABS DATEDIFF 電源
ACOS 弧度
ASIN(亞馬遜標準識別號碼) 圓形
ATAN 經驗值 標誌
ATN2 地板 新加坡樟宜機場
天花板 ISNULL(檢查是否為空值) 廣場
合併 ISNUMERIC SQRT
COS 日誌
嬰兒 床 LOG10
資料長度 月份
DATEADD NULLIF(SQL 中用於檢查兩個輸入是否相等並返回 NULL 的函數)

下列函式不一定具有決定性,但在以決定性方式指定索引檢視表或計算數據行上的索引時,可以使用這些函數。

功能 評論
所有聚合函數 除非使用 OVER 和 ORDER BY 子句指定所有聚合函數,否則所有聚合函數都是具決定性的。 如需這些函式的清單,請參閱聚合函數(Transact-SQL)。
除非搭配、 smalldatetimesql_variant使用datetime,否則具決定性。
轉換 除非下列其中一個條件存在,否則具決定性:

來源類型為 sql_variant

目標類型為 sql_variant ,且其來源類型為非決定性。

來源或目標類型為 datetimesmalldatetime,另一個來源或目標類型為字元字串,並指定非決定性樣式。 若要具決定性,樣式參數必須是常數。 此外,小於或等於 100 的樣式不具決定性,但樣式 20 和 21 除外。 大於 100 的樣式具決定性,但樣式 106、107、109 和 113 除外。
校驗和 具決定性,但 CHECKSUM*除外。
ISDATE 只有當與 CONVERT 函式搭配使用時,才會指定 CONVERT 樣式參數,且 style 不等於 0、100、9 或 109。
蘭德 只有在指定 種子 參數時,RAND 才會具決定性。

所有組態、數據指標、元數據、安全性和系統統計函式都是非決定性的。 如需這些函式的清單,請參閱組態函式(Transact-SQL)數據指標函式(Transact-SQL)、元數據函式(Transact-SQL)安全性函式(Transact-SQL)系統統計函數(Transact-SQL)。

下列來自其他類別的內建函式一律為非決定性。

@@連結 GETDATE
@@CPU_忙碌 GETUTCDATE 函數(取得當前 UTC 日期)
@@DBTS 獲取傳輸狀態
@@IDLE 滯後
@@IO_BUSY 最後值
@@MAX_CONNECTIONS 領導
包裹已收到 最小活動列版本 (MIN_ACTIVE_ROWVERSION)
@@PACK_SENT NEWID
保持 @@PACKET_ERRORS 不變。 NEWSEQUENTIALID
@@TIMETICKS 取得下一個值
@@TOTAL_ERRORS NTILE
總讀數 PARSENAME
寫入總量 PERCENTILE_CONT(連續百分位數)
CUME_DIST 百分位數離散函数
CURRENT_TIMESTAMP 百分比排名
DENSE_RANK 蘭德
第一個值 等級
ROW_NUMBER
TEXTPTR

從函式呼叫擴充預存程式

呼叫擴充預存程式的函式不具決定性,因為擴充預存程式可能會對資料庫造成副作用。 副作用是資料庫的全域狀態變更,例如數據表更新或外部資源,例如檔案或網路;例如,修改檔案或傳送電子郵件訊息。 從使用者定義函數執行擴充預存程式時,您不應該依賴傳回一致的結果集。 不建議在資料庫上建立副作用的使用者定義函式。

從函式內部呼叫時,擴充預存程式無法將結果集傳回給用戶端。 傳回結果集給用戶端的任何 Open Data Services API 都會有 FAIL 的傳回碼。

擴充預存程序可以返回連接到 SQL Server。 不過,程式無法聯結與叫用擴充預存程式的原始函式相同的交易。

類似於批次或預存程序的調用,延伸預存程序會在執行 SQL Server 的 Microsoft Windows 安全性帳戶的上下文中執行。 擴充預存程式的擁有者在將許可權授與其他使用者執行程式時,應考慮此情況。