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

更新 : 2006 年 7 月 17 日

決定的関数は、一連の特定の入力値で呼び出され、かつデータベースの状態が同じ場合は、必ず同じ結果を返します。非決定的関数は、アクセスするデータベースの状態が同じ場合でも、一連の特定の入力値で呼び出すたびに、異なる結果を返すことがあります。

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

このトピックでは、組み込みのシステム関数の決定性について説明し、およびユーザー定義関数の決定的なプロパティに拡張ストアド プロシージャへの呼び出しが含まれている場合のこのプロパティへの影響を確認します。

組み込み関数の決定性

組み込み関数の決定性には、影響を与えることができません。各組み込み関数が決定的であるか非決定的であるかは、Microsoft SQL Server 2005 による関数の実装方法に基づきます。

組み込みの集計関数と文字列関数はすべて決定的関数です。これらの関数の一覧については、「集計関数 (Transact-SQL)」および「文字列関数 (Transact-SQL)」を参照してください。

集計関数および文字列関数以外のカテゴリに属する次の組み込み関数は、常に決定的関数になります。

ABS

DATEDIFF

PARSENAME

ACOS

DAY

POWER

ASIN

DEGREES

RADIANS

ATAN

EXP

ROUND

ATN2

FLOOR

SIGN

CEILING

ISNULL

SIN

COALESCE

ISNUMERIC

SQUARE

COS

LOG

SQRT

COT

LOG10

TAN

DATALENGTH

MONTH

YEAR

DATEADD

NULLIF

 

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

関数 コメント

CAST

datetime 型、smalldatetime 型、または 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 は、seed パラメータが指定されている場合にのみ決定的です。

構成、カーソル、メタデータ、セキュリティ、およびシステム統計関数はすべて、非決定的関数です。これらの関数の一覧については、「構成関数 (Transact-SQL)」、「カーソル関数 (Transact-SQL)」、「メタデータ関数 (Transact-SQL)」、「セキュリティ関数 (Transact-SQL)」、および「システム統計関数 (Transact-SQL)」を参照してください。

他のカテゴリに属する次の組み込み関数は、常に非決定的関数になります。

@@CONNECTIONS

@@TOTAL_READ

@@CPU_BUSY

@@TOTAL_WRITE

@@DBTS

CURRENT_TIMESTAMP

@@IDLE

GETDATE

@@IO_BUSY

GETUTCDATE

@@MAX_CONNECTIONS

GET_TRANSMISSION_STATUS

@@PACK_RECEIVED

MIN_ACTIVE_ROWVERSION

@@PACK_SENT

NEWID

@@PACKET_ERRORS

NEWSEQUENTIALID

@@TIMETICKS

RAND

@@TOTAL_ERRORS

TEXTPTR

関数からの拡張ストアド プロシージャの呼び出し

拡張ストアド プロシージャはデータベースに副作用を及ぼす可能性があるため、拡張ストアド プロシージャを呼び出す関数は非決定的関数です。副作用とはデータベースのグローバル状態の変更を指し、たとえば、テーブルの更新や、ファイルやネットワークなどの外部リソースの更新 (ファイルの変更、電子メール メッセージの送信) などが挙げられます。ユーザー定義関数から拡張ストアド プロシージャを実行した場合は、一貫性のある結果セットが返される保証はありません。データベースに副作用を与えるユーザー定義関数の使用はお勧めしません。

拡張ストアド プロシージャは、関数の中から呼び出されると、クライアントに結果セットを返すことができません。クライアントに結果セットを返すすべてのオープン データ サービス API のリターン コードは、FAIL になります。

拡張ストアド プロシージャは、SQL Server に接続し直すことができますが、その拡張ストアド プロシージャを呼び出した元の関数と同じトランザクションに参加することはできません。

拡張ストアド プロシージャは、バッチまたはストアド プロシージャから呼び出された場合と同様に、SQL Server を実行している Microsoft Windows セキュリティ アカウントのコンテキストで実行されます。拡張ストアド プロシージャの所有者は、プロシージャを実行する権限を他のユーザーに許可するときに、このことを考慮する必要があります。

参照

概念

ユーザー定義関数のデザイン ガイドライン
ユーザー定義テーブル値関数
インライン ユーザー定義関数
関数としてのストアド プロシージャの書き直し

その他の技術情報

ユーザー定義関数の設計

ヘルプおよび情報

SQL Server 2005 の参考資料の入手

変更履歴

リリース 履歴
変更内容 :
  • CONVERT 関数の説明を追加し、CONVERT を使用する場合、変換元または変換先の型が datetime または smalldatetime で、変換元または変換先の型が文字列で、非決定的なスタイルが指定されている場合を除いて、決定的な結果になることを明確にしました。
  • また、決定的なスタイルと非決定的なスタイルを明確にしました。