共用方式為


決定性與非決定性函式

適用於:sql Server Azure SQL 資料庫 Azure SQL 受控執行個體 Microsoft Fabric Microsoft Fabric SQL 資料庫中Microsoft網狀架構倉儲中的 SQL 分析端點

假設資料庫狀態相同,任何時候以特定的輸入值集來呼叫決定性函式時,一律會傳回相同的結果。 非確定性函式每次使用一組特定輸入值呼叫時,可能會傳回不同的結果,即使它們存取的資料庫狀態保持不變也一樣。 例如,函數一 AVG 律會傳回相同的結果,以先前所述的限定條件,但 GETDATE 傳回目前日期時間值的函數一律會傳回不同的結果。

無論是透過呼叫函式的計算資料行的索引,還是透過參考函式的索引檢視表,使用者自訂函式的幾項屬性都決定了 SQL Server 資料庫引擎為函式結果編製索引的能力。 函數的決定性是這類屬性的一種。 例如,如果檢視參考了任何非決定性函式,就無法在檢視上建立叢集索引。 如需函式屬性的詳細資訊,包括決定性,請參閱 使用者定義函式

決定性函數必須繫結結構描述。 建立決定性函數時,需使用 SCHEMABINDING 子句。

本文會說明內建系統函式的決定性,以及當使用者自訂函式的決定性屬性包含擴充預存程序的呼叫時,所造成的影響。

判斷函數是否為確定性

您可以查詢函式的 is_deterministic 物件屬性,以確認函式是否為決定性。 下列範例會判斷函式 Sales.CalculateSalesTax 是否為確定性。

SELECT OBJECTPROPERTY(OBJECT_ID('Sales.CalculateSalesTax'), 'IsDeterministic');

內建函式決定性

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

所有的字串內建函式都具有決定性,除了 FORMAT 以外。 如需這些函式的清單,請參閱字 串函式

在下列內建函數類別目錄中,不屬於字串函數的內建函數一律會視為具有決定性。

  • ABS
  • ACOS
  • ASIN
  • ATAN
  • ATN2
  • CEILING
  • COALESCE
  • COS
  • COT
  • DATALENGTH
  • DATEADD
  • DATEDIFF
  • DAY
  • DEGREES
  • EXP
  • FLOOR
  • ISNULL
  • ISNUMERIC
  • LOG
  • LOG10
  • MONTH
  • NULLIF
  • POWER
  • RADIANS
  • ROUND
  • SIGN
  • SIN
  • SQRT
  • SQUARE
  • TAN
  • YEAR

下列函式不會永遠是決定性函式,但若是以決定性的方式來指定,則可用於索引檢視表或計算資料行的索引。

函式 註解
所有彙總函數 所有彙總函式都是確定性的,除非使用 and OVERORDER BY 子句指定它們。 如需這些函式的清單,請參閱 彙總函式
CAST 除非搭配使用 datetimesmalldatetimesql_variant,否則為決定性函數。
CONVERT 除非存在這些條件之一,否則為具決定性函數:

來源類型為 sql_variant

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

來源或目標類型為 datetimesmalldatetime;其他來源或目標類型為字元字串,而且指定了非決定性的樣式。 若要具有決定性,樣式參數必須是常數。 此外,小於或等於 100 的樣式不具決定性,但樣式 20 和 21 除外。 大於 100 的樣式具決定性,但樣式 106、107、109 和 113 除外。
CHECKSUM 確定性,但 CHECKSUM(*).
ISDATE 只有在與函式搭配 CONVERT 使用時才 CONVERT 會確定,才會指定樣式參數,且樣式不等於 0、100、9 或 109。
RAND RAND 只有在指定 種子 參數時才具有確定性。

所有的組態、資料指標、中繼資料、安全性及系統統計函數都是不具決定性的。 您可以查看這些函式的清單

下列屬於其他類別的內建函數,一律是不具決定性的。

  • @@CONNECTIONS
  • @@CPU_BUSY
  • @@DBTS
  • @@IDLE
  • @@IO_BUSY
  • @@MAX_CONNECTIONS
  • @@PACKET_ERRORS
  • @@PACK_RECEIVED
  • @@PACK_SENT
  • @@TIMETICKS
  • @@TOTAL_ERRORS
  • @@TOTAL_READ
  • @@TOTAL_WRITE
  • AT TIME ZONE
  • CUME_DIST
  • CURRENT_TIMESTAMP
  • DENSE_RANK
  • FIRST_VALUE
  • FORMAT
  • GETDATE
  • GETUTCDATE
  • GET_TRANSMISSION_STATUS
  • LAG
  • LAST_VALUE
  • LEAD
  • MIN_ACTIVE_ROWVERSION
  • NEWID
  • NEWSEQUENTIALID
  • NEXT VALUE FOR
  • NTILE
  • PARSENAME
  • PERCENTILE_CONT
  • PERCENTILE_DISC
  • PERCENT_RANK
  • RAND
  • RANK
  • ROW_NUMBER
  • TEXTPTR

從函式呼叫擴充預存程序

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

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

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

與批次或預存程序的叫用類似,擴充預存程序會在執行 SQL Server 的 Windows 安全性帳戶內容中執行。 擴充預存程序的擁有者在授與其他使用者執行該程序的權限時,應考慮此資訊安全內容的權限。