次の方法で共有


決定論的関数と非決定論的関数

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceMicrosoft Fabric の SQL 分析エンドポイントMicrosoft Fabric のウェアハウスMicrosoft Fabric プレビューの SQL データベース

決定論的関数は、一連の特定の入力値で呼び出され、かつデータベースの状態が同じ場合は、必ず同じ結果を返します。 非決定的関数は、アクセスするデータベースの状態が変わらない場合でも、特定の入力値のセットで呼び出されるたびに異なる結果を返す場合があります。 たとえば、 AVG 関数は、前に説明した修飾を指定すると常に同じ結果を返しますが、現在の datetime 値を返す GETDATE 関数は常に異なる結果を返します。

ユーザー定義関数には、関数を呼び出す計算列のインデックスを使用するか、または関数を参照するインデックス付きビューを使用して、関数の結果にインデックスを作成する SQL Server データベース エンジン の機能を決定する複数のプロパティがあります。 関数の決定性は、このようなプロパティの 1 つです。 たとえば、ビューがなんらかの非決定的関数を参照している場合、そのビューにはクラスター化インデックスを作成できません。 決定性を含む関数のプロパティの詳細については、「 ユーザー定義関数」を参照してください。

決定論的関数は、スキーマ バインドである必要があります。 決定論的関数を作成するときは、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

次の関数は必ず決定的関数になるとは限りませんが、決定論的な方法で指定されている場合は、インデックス付きビューまたは計算列のインデックスで使用できます。

機能 Comments
すべての集計関数 すべての集計関数は、 OVER 句と ORDER BY 句で指定されていない限り、決定論的です。 これらの関数の一覧については、「 集計関数」を参照してください。
CAST datetimesmalldatetime、または sql_variantと共に使用しない場合は、決定的関数になります。
CONVERT 以下の条件に該当しない場合は決定的関数になります。

ソースの型が sql_variantであること。

変換先の型が sql_variant であり、変換元の型が非決定的であること。

変換元または変換先の型が datetime または smalldatetimeであり、他の変換元または変換先の型が文字列で、非決定的スタイルが指定されていること。 決定的にするには、スタイル パラメーターを定数にする必要があります。 また、スタイルが 20 および 21 以外で 100 以下の場合は非決定的です。 スタイルが 101 以上で、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 セキュリティ アカウントのコンテキストで実行されます。 拡張ストアド プロシージャの所有者は、プロシージャを実行する権限を他のユーザーに許可するときに、このセキュリティ コンテキストのアクセス許可を考慮する必要があります。