CLR ルーチンのカスタム属性

更新 : 2006 年 4 月 14 日

ここで示す属性は、Microsoft SQL Server に登録される CLR (共通言語ランタイム) ルーチン、ユーザー定義型、およびユーザー定義集計に適用できます。属性が適用されない場合、SQL Server は既定値を想定します。ここで示す属性は、Microsoft.SqlServer.Server 名前空間で定義されています。

SqlUserDefinedAggregate 属性

SqlUserDefinedAggregate 属性は、ユーザー定義集計として登録する必要のあるメソッドを示します。すべてのユーザー定義集計にこのカスタム属性で注釈を付ける必要があります。

SqlUserDefinedAggregate[(aggregate-attribute [,...])]
aggregate-attribute::=
Format={Native | UserDefined}
IsInvariantToDuplicates= {true | false}
IsInvariantToNulls= {true | false}
IsInvariantToOrder= {true | false}
IsNullIfEmpty= {true | false}
| MaxByteSize= n 

この属性では、次に示すプロパティを使用します。

プロパティ 説明

Format

シリアル化形式を指定します。Format.Native または Format.UserDefined を指定できます。

IsInvariantToDuplicates

クエリ プロセッサによって使用されます。重複した値が存在しても集計が変化しない場合、このプロパティから true が返されます。つまり、集計 S, {X} は、X が既に S に含まれていれば、集計 S と同じになることを意味します。たとえば、MIN や MAX などの集計関数はこのプロパティの条件を満たしますが、SUM は満たしません。

IsInvariantToNulls

クエリ プロセッサによって使用されます。集計が NULL に対して変化しない場合、このプロパティから true が返されます。つまり、集計 S, {NULL} は、集計 S と同じになります。たとえば、MIN や MAX などの集計関数はこのプロパティの条件を満たしますが、COUNT(*) は満たしません。

IsInvariantToOrder

今後使用するために予約されています。このプロパティは、現時点ではクエリ プロセッサで使用されません。現行では、順序が保証されていません。

IsNullIfEmpty

クエリ プロセッサによって使用されます。積算されている値がなければ集計から NULL を返す場合、このプロパティは true を返します。

MaxByteSize

インスタンスの最大サイズをバイト単位で指定します。MaxByteSize は、UserDefined シリアル化形式と共に指定する必要があります。指定できる最大値は 8000 です。

ユーザー定義のシリアル化が指定された集計の場合、MaxByteSize はシリアル化されるデータの合計サイズを表します。10 文字 (System.Char) の文字列をシリアル化する集計について考えてみましょう。BinaryWriter を使用して文字列をシリアル化すると、シリアル化される文字列の合計サイズは 22 バイトになります。このサイズは、2 バイト (Unicode UTF-16 の文字 1 文字) に最大文字数を掛け、さらにバイナリ ストリームのシリアル化から生じるオーバーヘッドの制御バイトを 2 バイト加えたものです。そのため、MaxByteSize の値を決定するときは、シリアル化されるデータの合計サイズを考慮する必要があります。つまり、バイナリ形式でシリアル化されるデータのサイズに、シリアル化によって生じるオーバーヘッドを加算したサイズです。

SqlFunction 属性

SqlFunction 属性は、関数として登録する必要のあるメソッドを示します。この属性を使用する場合は、適切な関数属性セットを指定します。

SqlFunction[(function-attribute [,...])]
function-attribute::=
IsDeterministic= {true | false}
| DataAccess = { DataAccessKind.None | DataAccessKind.Read }
| SystemDataAccess = { SystemDataAccessKind.None | SystemDataAccessKind.Read }
| IsPrecise = { true | false }
| FillRowMethodName= string
| Name= string
| TableDefinition= string 

この属性では、次に示すプロパティを使用します。

プロパティ

説明

IsDeterministic

入力値とデータベースの状態が同じであれば、ユーザー定義関数が常に同じ出力値を生成する場合、そのユーザー定義関数を決定的関数と呼びます。IsDeterministic プロパティを True に設定することにより、関数を決定的関数としてマークすることができます。

IsDeterministic プロパティは、関数の結果のインデックスを、インデックス付き計算列やインデックス付きビューの形式で作成する場合にも有用です。このプロパティが指定されないと、関数は非決定的関数と想定されます。

SQL Server 2000 とは異なり、このバージョンの SQL Server では、"決定的" の定義を厳密にし、ローカル データへのアクセスが決定的となる関数だけに使用しています。データ アクセスの特性は、DataAccess プロパティと SystemDataAccess プロパティとで別々にキャプチャされます。

ユーザー定義関数では、リモート サーバーへのデータ アクセスを使用できることに注意してください。たとえば、こうした例として、SqlConnection を使用して別の SQL Server インスタンスに接続する場合が考えられます。ただし、この場合でも IsDeterministic を使用する必要があります。CLR 関数を決定的関数に設定した場合は、リモート サーバーで副作用が発生しないようにする必要があります。SQL Server ではコンテキスト接続に対する副作用は制限されますが、リモート接続に対する副作用は制限されません。

この属性の既定値は false です。

ms131050.note(ja-jp,SQL.90).gifメモ :

入力値とデータベースの状態が同じでも、関数が必ずしも常に同じ出力値を生成しない場合は、その関数を決定的関数としてマークしないでください。完全に決定的ではない関数を決定的関数としてマークした場合、インデックス付きビューと計算列が破損する可能性があります。

DataAccess

DataAccess プロパティは、ローカルの SQL Server に格納されたユーザー データに関数がアクセスするかどうかを判断します。また、トランザクションの統合が必要な場合 (既定)、リモート サーバーへの接続時にもこのプロパティが必要になります。このプロパティには次の 2 つのいずれかの値を指定できます。

  • DataAccessKind.None: データにアクセスしません。
  • DataAccessKind.Read: ユーザーのデータだけを読み取ります。

ms131050.note(ja-jp,SQL.90).gifメモ :

Transact-SQL クエリが CLR ルーチン内から実行される場合は、DataAccessKind.Read プロパティを設定する必要があります。

SystemDataAccess

このプロパティは、SQL Server のシステム カタログまたは仮想システム テーブルに格納されたデータに関数がアクセスする必要があるかどうかを示します。このプロパティには次の 2 つのいずれかの値を指定できます。

  • SystemDataAccessKind.None: システム データにアクセスしません。これは既定のオプションです。
  • SystemDataAccessKind.Read: システム データだけを読み取ります。

IsPrecise

これは、浮動小数点演算など、厳密な結果が算出されない計算がルーチンに含まれているかどうかを示すブール値のプロパティです。関数の有効桁数は、その関数を使用する計算列にインデックスを作成できるかどうかを判断するために使用するプロパティの 1 つです。この属性の既定値は false です。

FillRowMethodName

この属性は、TVF (テーブル値関数) に関連しています。この属性は、TVF のコントラクトで使用した TVF と同じクラス内のメソッド名を指定する文字列です。詳細については、「CLR テーブル値関数」を参照してください。

Name

関数を SQL Server に登録する際に使用する名前を表します。この属性は、Microsoft Visual Studio だけで使用され、指定されたメソッドがユーザー定義関数として自動的に登録されます。SQL Server では使用されません。

TableDefinition

メソッドが TVF として使用される場合、結果のテーブル定義を表す文字列です。この属性は、Visual Studio だけで使用され、指定されたメソッドが TVF として自動的に登録されます。SQL Server では使用されません。

次の例では、int 型と nvarchar(4000) 型の 2 つの列を Visual Studio から返す TVF を定義するために、どのようにこの属性を使用するかを示します。

[C#]

[SqlFunction(FillRowMethodName="FillRow1", TableDefinition = "Testid int, Testname nvarchar(4000)")]
public static IEnumerable TableFunctionExecute1(string str)

[Visual Basic]

<Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName:="FillRow1", TableDefinition:="Testid int, Testname nvarchar(4000)")>
Public Shared Function TableFunctionExecute1(ByVal str As String) As IEnumerable

SqlFacet 属性

SqlFacet 属性は、UDT (ユーザー定義型) 式の戻り値の型についての情報を返すために使用します。この属性は、void 以外の戻り値に対してのみ指定できます。この属性は、戻り値の型についての情報を提供することが目的であり、型に何を格納できるのかを "制約する" ために使用するのではありません。このため、フィールドのサイズを 2 文字にすることを示す SqlFacet がそのフィールドの属性に指定されている場合、フィールドへのアクセス式を表す SQL Server 型のサイズは 2 になりますが、そのフィールドへの代入はこのファセットでは制限されません。

SqlFacet[(facet-attribute [,...])]
facet-attribute::=
IsFixedLength= {true | false}
| MaxSize= { n }
| Precision = { n}
| Scale = { n}
| IsNullable = { true | false }

IsFixedLength

戻り値の型が固定長の場合は True です。MaxSize を -1 に設定する場合は、FALSE に設定する必要があります。既定値は FALSE です。

MaxSize

基になるフィールドの型の論理単位で表された最大サイズです。論理単位は、バイナリ フィールド型の場合はバイト (範囲 1 ~ 8000) で、文字フィールド型の場合は Unicode 文字の数 (範囲 1 ~ 4000) です。値 -1 はサイズの大きな文字型とサイズの大きなバイナリ型のために予約されています。既定値は、Unicode 文字型では 4000 で、バイナリ型では 8000 です。

Precision

戻り値の型の有効桁数です。数値型でのみ有効です。Precision プロパティを設定した場合、小数点以下桁数も指定する必要があります。最大サイズは 38 です。既定値は 38 です。

Scale

戻り値の型の小数点以下桁数です。小数型でのみ有効です。Scale プロパティを設定した場合、有効桁数も指定する必要があります。最大サイズは 38 です。既定値は 0 です。

IsNullable

戻り値に NULL 値を許容する場合は True です。既定値は TRUE です。

SqlFacet フィールドの型に有効なプロパティ

次の表に、特定のフィールドの型のさまざまなプロパティに有効な値を示します。この表では、"可" はプロパティが有効であることを示し、"不可" は無効であることを示します。

指定する SqlFacet は、フィールドの型と互換性がある必要があります。プロパティが無効の場合、ユーザーが既定値以外の値をそのプロパティに指定すると、型の登録時にエラーが報告されます。有効桁数と小数点以下桁数の最大値は 38 です。MaxSize の値は、1 ~ 8000 (バイナリ型の場合)、1 ~ 4000 (文字型の場合)、または -1 にする必要があります。それ以外の値は無効です。

データ型 IsFixedLength MaxSize Precision Scale IsNullable

SqlBoolean

不可

不可

不可

不可

SqlByte

不可

不可

不可

不可

SqlInt16

不可

不可

不可

不可

SqlInt32

不可

不可

不可

不可

SqlInt64

不可

不可

不可

不可

SqlSingle

不可

不可

不可

不可

SqlDouble

不可

不可

不可

不可

SqlDateTime

不可

不可

不可

不可

SqlMoney

不可

不可

不可

不可

SqlGuid

不可

不可

不可

不可

SqlDecimal

不可

不可

SqlString

不可

不可

SqlBinary

不可

不可

SqlXml

不可

不可

不可

不可

SqlBytes

不可

不可

SqlChars

不可

不可

SqlDate

不可

不可

不可

不可

SqlTime

不可

不可

不可

不可

埋め込み UDT

不可

不可

不可

不可

string

不可

不可

Byte[]

不可

不可

Char[]

不可

不可

decimal

不可

不可

不可

SqlProcedure 属性

SqlProcedure 属性は、ストアド プロシージャとして登録する必要のあるメソッドを示します。この属性は、Visual Studio だけで使用され、指定されたメソッドがストアド プロシージャとして自動的に登録されます。SQL Server では使用されません。

SqlProcedure [(procedure-attribute[ ,... ])]
procedure-attribute::=
Name = "procedure name"

この属性では、次に示すプロパティを使用します。

Name

Name プロパティは省略できます。このプロパティはストアド プロシージャ名を指定します。

ms131050.note(ja-jp,SQL.90).gifメモ :
SqlProcedure 属性は、Visual Studio 開発環境以外では省略できます。

SqlTrigger 属性

SqlTrigger 属性は、トリガとして登録する必要のあるメソッドを示します。

SqlTrigger [(trigger-attribute[ ,... ])]

trigger-attribute::=
    Target = " table-name "  
  | Event = "trigger-type update-action [, ...]"

trigger-type::=
    FOR | AFTER | INSTEAD OF

update-action::=
    UPDATE | DELETE | INSERT

この属性では、次に示すプロパティを使用します。

Target

これは必須のプロパティです。トリガを適用するテーブルを指定します。

Event

これは必須のプロパティです。トリガの種類と、トリガを起動する DML (データ操作言語) 操作を指定します。DML 操作は UPDATE 操作、DELETE 操作、または INSERT 操作です。トリガの種類には AFTER または INSTEAD OF を指定できます。トリガの種類として FOR を指定すると、AFTER を指定した場合と同義になります。

SqlUserDefinedTypeAttribute

SqlUserDefinedTypeAttribute をアセンブリのクラス定義に適用できます。SQL Server では、これにより、このカスタム属性を持つクラス定義にバインドされたユーザー定義型が作成されます。

SqlUserDefinedTypeAttribute[(udt-property [,...])]

udt-property::=
    Format={Native | UserDefined}
  | MaxByteSize= n 
  | IsByteOrdered= {true | false}
  | ValidationMethod=<validate_method_name>
  | IsFixedLength = {true | false}
  | Name = <SQL_type_name>

この属性では、次に示すプロパティを使用します。

プロパティ 説明

Format

シリアル化形式を指定します。Format.Native または Format.UserDefined を指定できます。ネイティブ シリアル化は、UDT のデータ型によって異なります。

MaxByteSize

インスタンスのバイト単位の最大サイズ。MaxByteSizeUserDefined シリアル化形式と共に指定する必要があります。MaxByteSize は、1 ~ 8000 にする必要があります。この属性は、Native シリアル化形式と共に使用しないでください。

UDT にユーザー定義のシリアル化を指定した場合、MaxByteSize は、ユーザーが定義した形式でシリアル化された UDT の合計サイズを表します。10 文字 (System.Char) の文字列プロパティを持つ UDT を考えてみましょう。BinaryWriter を使用して文字列をシリアル化すると、シリアル化される文字列の合計サイズは 22 バイトになります。このサイズは、2 バイト (Unicode UTF-16 の文字 1 文字) に最大文字数を掛け、さらにバイナリ ストリームのシリアル化から生じるオーバーヘッドの制御バイト 2 バイトを加えたものです。そのため、MaxByteSize の値を決定するときは、シリアル化されたデータの合計サイズを考慮する必要があります。つまり、バイナリ形式でシリアル化されるデータのサイズに、シリアル化によって生じるオーバーヘッドを加えたサイズです。

IsByteOrdered

SQL Server で実行される UDT のバイナリの比較方法を決定するブール値。true の場合、SQL Server ではその UDT はバイト表現と同じ順序付けであると想定されます。この属性が設定された型の列にインデックスを作成できるようにするには、このプロパティを true にする必要があります。

ValidationMethodName

この属性によって指定されるメソッドは、UDT を信頼のないバイナリ値からシリアル化解除するときに、その UDT のインスタンスを検証するために使用します。

IsFixedLength

対象の型のすべてのインスタンスが同じ長さかどうかを決定するブール値です。true に設定した場合、対象の CLR 型に対応している UDT のすべてのインスタンスを MaxByteSize と厳密に等しい長さ (バイト単位) にする必要があります。この属性は、UserDefined シリアル化形式が指定された UDT だけに関連します。

Name

型の SQL Server 名です。SQL Server では使用されませんが、Visual Studio .NET プロジェクト システムによって使用されます。

SqlMethod 属性

SqlMethod 属性は、UDT のメソッドまたはプロパティの決定性およびデータ アクセス プロパティを示すために使用します。プロパティについては、setter または getter に直接 SqlMethod 属性を使用する必要があります。SqlMethod 属性には、すべての SqlFunction プロパティを含むプロパティ セットと、新しい 2 つのプロパティがあります。

ms131050.note(ja-jp,SQL.90).gifメモ :
SqlMethodAttribute クラスは SqlFunctionAttribute クラスから継承されるので、SqlMethodAttributeFillRowMethodName フィールドと TableDefinition フィールドを SqlFunctionAttribute から継承します。これは、一見テーブル値メソッドを記述できることを示していますが、この場合には該当しません。テーブル値メソッドはコンパイルされ、そのアセンブリが配置されますが、実行時に戻り値の IEnumerable 型に関するエラーが発生し、次のメッセージが表示されます。"アセンブリ '<assembly>' のクラス '<class>' のメソッド、プロパティ、またはフィールド '<name>' の戻り値の型が無効です。"
SqlMethod [ ( method-attribute [ ,... ] ) ]
method-attribute::= 
    IsDeterministic= { true | false }, default is false
  | IsPrecise= {true | false}
  | IsMutator = { true | false }
  | OnNullCall = { true | false }
  | InvokeIfReceiverIsNull= { true | false }, default is false
  | DataAccess = { DataAccessKind.None | DataAccessKind.Read }
  | SystemDataAccess = { SystemDataAccessKind.None | SystemDataAccessKind.Read }
  | FillRowMethodName= string
  | Name= string
  | TableDefinition= string

IsDeterministic を true に設定すると、メソッドやプロパティが決定的として設定されます。既定値は false です。

OnNullCall を指定した場合、値 true は、メソッドの呼び出しに NULL 引数が指定された場合にそのメソッドが呼び出されることを示します。false は、入力が NULL の場合には、そのメソッドの結果に NULL 値を想定する必要があることを示します。OnNullCall の既定値は true です。

IsMutator プロパティを true に設定した場合、メソッドの戻り値の型は void になります。SQL Server ではそのメソッドがミューテータとして設定されます。ミューテータ メソッドは、UDT インスタンスの状態を変化させるメソッドです。ミューテータ メソッドは、代入ステートメントまたはデータ変更ステートメントで呼び出せますが、クエリで使用することはできません。あるメソッドがミューテータとして設定され、そのメソッドから void が返されない場合、CREATE TYPE は失敗しませんが、エラーが発生します。void 以外の値が返された場合、エラーは発生しませんが、返された値にアクセスすることはできず、値を使用することもできません。既定値は false です。SqlMethod 属性が setter で使用され、IsMutator が TRUE に設定されている場合、プロパティをミューテータにすることができます。ただし、プロパティ setter はミューテータとして暗黙的に処理されるため、SqlMethod 属性の IsMutator プロパティを TRUE に設定する必要はありません。

InvokeIfReceiverIsNull の既定値は false です。つまり、メソッドは NULL インスタンスでは呼び出されません。InvokeIfReceiverIsNull が true の場合は、メソッドの戻り値はメソッドの型によって決まります。メソッドの戻り値の型で NULL 値が許容される場合、それぞれの型の NULL 値が返されます。戻り値の型に NULL 値が許容されない場合、型の既定の CLR 値が返されます。参照型の既定値は NULL ですが、値型の既定値は、型の既定のコンストラクタを呼び出した結果によって異なります。

参照

概念

CLR ユーザー定義型
CLR ストアド プロシージャ
CLR トリガ

その他の技術情報

CLR ユーザー定義集計
CLR ユーザー定義関数

ヘルプおよび情報

SQL Server 2005 の参考資料の入手

変更履歴

リリース 履歴

2006 年 4 月 14 日

更新内容 :
  • ミューテータ メソッドが void 以外の値を返す場合でも、CREATE TYPE ステートメントは失敗しないという内容を「SqlMethod 属性」のセクションに追加しました。
  • IsDeterministic プロパティを使用して、完全に決定的ではない関数を決定的関数としてマークすることの危険性に関する記述を追加しました。