CLR ユーザー定義集計の要件
CLR (共通言語ランタイム) アセンブリの型は、必要な集計コントラクトが実装されていれば、ユーザー定義集計関数として登録できます。このコントラクトは、SqlUserDefinedAggregate 属性と集計コントラクトのメソッドで構成されます。集計コントラクトには、集計の中間状態を保存するためのメカニズムと、Init、Accumulate、Merge、および Terminate の 4 つのメソッドで構成される新しい値を積算するメカニズムが含まれます。これらの要件を満たしていれば、ユーザー定義集計の豊富なメリットを Microsoft SQL Server 2005 で有効に活用できます。このトピックの次のセクションでは、ユーザー定義集計を作成し、そのユーザー定義集計を使用して作業する方法について詳しく説明します。例については、「CLR ユーザー定義集計関数の呼び出し」を参照してください。
SqlUserDefinedAggregate
すべてのユーザー定義集計には SqlUserDefinedAggregate カスタム属性で注釈を付ける必要があります。この属性により、型がユーザー定義集計のコントラクトに従っていることが SQL Server に通知されます。SqlUserDefinedAggregate 属性には、使用されるシリアル化形式を制御する 2 つの必須プロパティがあります。次の表では、これらのプロパティについて説明します。
プロパティ | 説明 |
---|---|
Format |
この型のシリアル化形式です。シリアル化形式には、ネイティブまたはユーザー定義のいずれかを指定できます。各シリアル化形式には独自の要件セットがあります。 |
MaxByteSize |
計算中にこの集計の状態を格納するために必要な最大サイズ (バイト単位) です。許容最大値は 8,000 です。ユーザー定義シリアル化が指定されている集計の場合、MaxByteSize はシリアル化されるデータの合計サイズを示します。10 文字の文字列 (System.Char) をシリアル化する集計について考えてみましょう。BinaryWriter を使用して文字列をシリアル化すると、シリアル化される文字列の合計サイズは 22 バイトになります。このサイズは、2 バイト (Unicode UTF-16 の文字 1 文字) に最大文字数を掛け、さらにバイナリ ストリームのシリアル化から生じるオーバーヘッドの制御バイト 2 バイトを加えたものです。そのため、MaxByteSize の値を決定するときは、シリアル化されるデータの合計サイズを考慮する必要があります。つまり、バイナリ形式でシリアル化されるデータのサイズに、シリアル化によって生じるオーバーヘッドを加えたサイズです。 |
SqlUserDefinedAggregate 属性は、いくつかの点で SqlUserDefinedType 属性と似ています。この属性も型のシリアル化に使用する形式を受け取り、最大サイズを指定するからです。次の表に、この属性の他のプロパティの概要を示します。
IsInvariantToDuplicates |
省略可能なプロパティです。値が重複しても集計が変化しない場合のみ true を返します。たとえば、MAX 関数や MIN 関数はこの条件を満たしますが、SUM 関数は満たしません。 |
IsInvariantToNulls |
省略可能なプロパティです。NULL 値が存在する場合に集計が変化するかどうかを示します。たとえば、MIN 関数や SUM 関数はこの条件を満たしますが、COUNT 関数は満たしません。 |
IsInvariantToOrder |
今後使用するために予約されています。このプロパティは、現時点ではクエリ プロセッサで使用されません。現行では、順序が保証されていません。 |
IsNullIfEmpty |
クエリ プロセッサによって使用されるプロパティです。積算されている値がない場合、集計から NULL を返すかどうかを示します。 |
クエリ プロセッサでは、集計の一時結果を作業テーブルに反映する必要があるときに、シリアル化を使用します。SqlUserDefinedAggregate 属性の詳細については、.NET Framework SDK の「SqlUserDefinedAggregateAttribute Class」を参照してください。
集計のメソッド
ユーザー定義集計として登録するクラスでは、次のインスタンス メソッドをサポートする必要があります。次に、集計を計算するためにクエリ プロセッサで使用されるメソッドを示します。
public void Init(); /* needed for empty group */
クエリ プロセッサは、このメソッドを使用して集計計算を初期化します。このメソッドは、クエリ プロセッサで集計されるグループごとに 1 回ずつ呼び出されます。クエリ プロセッサでは、複数のグループの集計を計算するために、集計クラスの同じインスタンスの再利用を選択することがあります。Init メソッドは、現在のインスタンスが以前に使用されていれば必要になるクリーンアップを実行し、新たな集計計算を再開できるようにします。
public void Accumulate ( input-type value);
input_type には、CREATE AGGREGATE ステートメントの input_sqltype で指定された SQL Server ネイティブ データ型に相当する SQL Server マネージ データ型を指定する必要があります。詳細については、「SQL Server データ型と .NET Framework データ型の対応」を参照してください。
UDT (ユーザー定義型) の場合、input-type 型は UDT 型と同じです。クエリ プロセッサでは、このメソッドを使用して集計値を積算します。このメソッドは、集計されるグループの値ごとに 1 回ずつ呼び出されます。クエリ プロセッサでは、集計クラスの特定のインスタンスの Init メソッドが呼び出された後にのみ、常に、このメソッドが呼び出されます。このメソッドの実装では、渡された引数値の積算を反映してインスタンスの状態を更新する必要があります。
public void Merge( udagg_class value);
このメソッドは、この集計クラスの別のインスタンスを現在のインスタンスとマージする場合に使用できます。クエリ プロセッサでは、このメソッドを使用して、1 つの集計の複数の部分計算をマージできます。
public return_type Terminate();
このメソッドは、集計計算を完了し、集計の結果を返します。return_type には、CREATE AGGREGATE ステートメントで指定された return_sqltype のマネージ データ型に相当する SQL Server マネージ データ型を指定する必要があります。また、return_type には、ユーザー定義型を指定することもできます。
参照
概念
CLR ユーザー定義型
CLR ユーザー定義集計関数の呼び出し