每當使用一組特定的輸入值呼叫時,具決定性函數一律會傳回相同的結果,並指定資料庫相同的狀態。 即使存取的資料庫狀態保持不變,非決定性函式每次使用一組特定的輸入值呼叫時,都可能會傳回不同的結果。 例如,根據上述限定性,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)。 |
| 投 | 除非搭配、 smalldatetime或 sql_variant使用datetime,否則具決定性。 |
| 轉換 | 除非下列其中一個條件存在,否則具決定性: 來源類型為 sql_variant。目標類型為 sql_variant ,且其來源類型為非決定性。來源或目標類型為 datetime 或 smalldatetime,另一個來源或目標類型為字元字串,並指定非決定性樣式。 若要具決定性,樣式參數必須是常數。 此外,小於或等於 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 安全性帳戶的上下文中執行。 擴充預存程式的擁有者在將許可權授與其他使用者執行程式時,應考慮此情況。