ユーザー定義型の作成 - 要件
適用対象: SQL Server
Microsoft SQL Server にインストールするユーザー定義型 (UDT) を作成するときは、いくつかの重要な設計上の決定を行う必要があります。 ほとんどの場合は、UDT を構造体として作成することをお勧めしますが、クラスとして作成することもできます。 UDT 定義を SQL Server に登録するには、UDT を作成するための仕様に準拠している必要があります。
UDT の実装要件
SQL Server で実行するには、UDT 定義に次の要件を実装する必要があります。
UDT では、 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute を指定する必要があります。 System.SerializableAttribute の使用は省略可能ですが、推奨されます。
UDT は、パブリック static (Microsoft Visual Basic では Shared) Null メソッドを作成して、クラスまたは構造体に System.Data.SqlTypes.INullable インターフェイスを実装する必要があります。 SQL Server は、既定では null 対応です。 この作業は、UDT で実行されるコードが NULL 値を認識するために必要です。
UDT には、解析をサポートするパブリック static (または Shared) Parse メソッドと、オブジェクトの文字列形式に変換するためのパブリック ToString メソッドが含まれている必要があります。
ユーザー定義のシリアル化形式の UDT は、 System.Data.IBinarySerialize インターフェイスを実装し、 Read および Write メソッドを提供する必要があります。
UDT は、 System.Xml.Serialization.IXmlSerializableを実装する必要があります。または、標準のシリアル化をオーバーライドする必要がある場合は、すべてのパブリック フィールドとプロパティが XML シリアル化可能な型であるか、 XmlIgnore 属性で修飾されている必要があります。
UDT オブジェクトのシリアル化は 1 つだけ存在する必要があります。 シリアル化ルーチンまたはシリアル化解除ルーチンでは、特定のオブジェクトの表現が複数認識されると検証が失敗します。
SqlUserDefinedTypeAttribute.IsByteOrdered must be true to compare data in byte order. IComparable インターフェイスが実装されておらず、 SqlUserDefinedTypeAttribute.IsByteOrdered が false の場合、バイト順の比較は失敗します。
クラスで定義する UDT には、引数を受け取らないバプリック コンストラクターを含める必要があります。 必要に応じて、オーバーロードのクラス コンストラクターを追加作成できます。
UDT では、データ要素をパブリック フィールドまたはプロパティ プロシージャとして公開する必要があります。
パブリック名は 128 文字を超えることはできません。また、 Database Identifiers で定義されている識別子の SQL Server 名前付け規則に準拠する必要があります。
sql_variant 列には UDT のインスタンスを含めることはできません。
SQL Server 型システムは UDT 間の継承階層を認識していないため、継承されたメンバーには Transact-SQL からアクセスできません。 ただし、型のマネージド コード実装では、継承を使用してクラスを構造化したり、そのクラスのメソッドを呼び出すことができます。
クラス コンストラクター以外のメンバーはオーバーロードできません。 オーバーロードされたメソッドを作成する場合、アセンブリを登録したり、SQL Server で型を作成したりしてもエラーは発生しません。 オーバーロード メソッドが検出されるのは、型の作成時ではなく実行時です。 オーバーロード メソッドは、呼び出されない限りクラス内に存在することができます。 エラーは、オーバーロード メソッドを呼び出した時点で発生します。
static (または Shared) メンバーは、定数または読み取り専用として宣言する必要があります。 静的メンバーを変更可能にすることはできません。
SqlUserDefinedTypeAttribute.MaxByteSize フィールドが -1 に設定されている場合、シリアル化された UDT は、ラージ オブジェクト (LOB) サイズ制限 (現在 2 GB) と同じ大きさにすることができます。 UDT のサイズは、 MaxByteSized フィールドで指定された値を超えることはできません。
Note
比較を実行するためにサーバーでは使用されませんが、必要に応じて、単一のメソッドである CompareTo を公開する System.IComparable インターフェイスを実装できます。 このインターフェイスは、クライアント側で UDT 値を正確に比較したり並べ替える場合に使用します。
ネイティブ シリアル化
UDT に適したシリアル化属性は、作成する UDT の種類によって異なります。 Native シリアル化形式では、SQL Server が UDT の効率的なネイティブ表現をディスクに格納できるようにする非常に単純な構造が利用されます。 UDT が単純で、次の型のフィールドのみが含まれている場合は、 Native 形式をお勧めします。
bool、 byte、 sbyte、 short、 ushort、 int、 uint、 long、 ulong、 float、 double、 SqlByte、 SqlInt16、 SqlInt32、 SqlInt64、 SqlDateTime、 SqlSingle、 SqlDouble、 SqlMoney、 SqlBoolean
上記の型のフィールドで構成される値型は、Visual C# の構造体 ( Visual Basic で知られている) などのNative形式の候補として適しています。 たとえば、 Native シリアル化形式で指定された UDT には、 Native 形式で指定された別の UDT のフィールドが含まれている場合があります。 UDT 定義がより複雑で、上記のリストにないデータ型が含まれている場合は、代わりに UserDefined シリアル化形式を指定する必要があります。
Native 形式には、次の要件があります。
型では、 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize の値を指定しないでください。
すべてのフィールドがシリアル化可能である必要があります。
UDT が構造体ではなくクラスで定義されている場合、 System.Runtime.InteropServices.StructLayoutAttribute を StructLayout.LayoutKindSequential として指定する必要があります。 この属性は、データ フィールドの物理レイアウトを制御し、メンバーを出現順にレイアウトするために使用します。 SQL Server では、この属性を使用して、複数の値を持つ UDT のフィールドの順序を決定します。
Native シリアル化で定義された UDT の例については、「ユーザー定義型のコーディング」の「ポイント UDT」を参照してください。
ユーザー定義シリアル化
Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 属性の UserDefined 形式設定により、開発者はバイナリ形式を完全に制御できます。 Format 属性プロパティを UserDefined として指定する場合は、コードで次の操作を行う必要があります。
省略可能な IsByteOrdered 属性プロパティを指定します。 既定値は false です。
Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute の MaxByteSize プロパティを指定します。
System.Data.Sql.IBinarySerialize インターフェイスを実装して、UDT の Read メソッドと Write メソッドを実装するコードを記述します。
UserDefined シリアル化で定義された UDT の例については、「ユーザー定義型のコーディングの通貨 UDT」を参照してください。
Note
UDT フィールドをインデックス化するには、ネイティブ シリアル化を使用するか、UDT フィールドを保存する必要があります。
シリアル化属性
UDT のストレージ表現を構築し、クライアントに UDT を値として転送するためにシリアル化を使用する方法は、属性で決まります。 UDT の作成時に、 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute を指定する必要があります。 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 属性は、クラスが UDT であることを示し、UDT のストレージを指定します。 必要に応じて、 Serializable 属性を指定できますが、SQL Server では必須ではありません。
Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute には次のプロパティがあります。
形式
UDT のデータ型に応じて、シリアル化形式 Native または UserDefined を指定します。
IsByteOrdered
SQL Server が UDT でバイナリ比較を実行する方法を決定する Boolean 値。
IsFixedLength
この UDT のすべてのインスタンスの長さが同じであるかどうかを示します。
MaxByteSize
インスタンスのバイト単位の最大サイズ。 UserDefined シリアル化形式で MaxByteSize を指定する必要があります。 ユーザー定義シリアル化が指定された UDT の場合、 MaxByteSize は、ユーザーが定義したシリアル化された形式の UDT の合計サイズを参照します。 MaxByteSize の値は、1 から 8000 の範囲であるか、UDT が 8,000 バイトを超えている (合計サイズが最大 LOB サイズを超えることはできません) ことを示す -1 に設定する必要があります。 10 文字の文字列 (System.Char) のプロパティを持つ UDT について考えます。 BinaryWriter を使用して UDT をシリアル化すると、シリアル化された文字列の合計サイズは 22 バイトになります。このサイズは、2 バイト (Unicode UTF-16 の文字 1 文字) に最大文字数を掛け、さらにバイナリ ストリームのシリアル化から生じるオーバーヘッドの制御バイト 2 バイトを加えたものです。 したがって、 MaxByteSize の値を決定するときは、シリアル化された UDT の合計サイズ (バイナリ形式でシリアル化されたデータのサイズとシリアル化によって発生するオーバーヘッド) を考慮する必要があります。
ValidationMethodName
UDT のインスタンスの検証に使用するメソッドの名前。
IsByteOrdered の設定
Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered プロパティが true に設定されている場合、実際には、シリアル化されたバイナリ データを情報のセマンティック順序付けに使用できることを保証します。 したがって、バイト順の UDT オブジェクトの各インスタンスは、シリアル化された表現を 1 つだけ持つことができます。 シリアル化されたバイトに対して SQL Server で比較操作を実行する場合、その結果は、マネージド コードで同じ比較操作が行われた場合と同じである必要があります。 次の機能は、 IsByteOrdered が true に設定されている場合にもサポートされます。
この型の列にインデックスを作成する機能。
この型の列に CHECK 制約と UNIQUE 制約だけでなく主キーと外部キーを作成する機能。
Transact-SQL ORDER BY、GROUP BY、PARTITION BY 句を使用する機能。 これらの句を使用した場合、順序の決定には型のバイナリ表現が使用されます。
Transact-SQL ステートメントで比較演算子を使用する機能。
この型の計算列を保存する機能。
Native と UserDefined シリアル化形式の両方で、IsByteOrdered が true に設定されている場合、次の比較演算子がサポートされることに注意してください
と等しい (=)
等しくない (!=)
より大きい (>)
より小さい (<)
以上 (>=)
以下 (<=)
NULL 値の許容属性の実装
アセンブリの属性を正しく指定することに加えて、クラスで NULL 値の許容属性をサポートする必要があります。 SQL Server に読み込まれる UDT は null 対応ですが、UDT が null 値を認識するには、クラスで INullable インターフェイスを実装する必要があります。 UDT で null 許容を実装する方法の詳細と例については、「 ユーザー定義型のコーディングを参照してください。
文字列の変換
UDT との間の文字列変換をサポートするには、クラスに Parse メソッドと ToString メソッドを指定する必要があります。 Parse メソッドを使用すると、文字列を UDT に変換できます。 static (または Visual Basic では Shared) として宣言し、System.Data.SqlTypes.SqlString 型のパラメーターを受け取る必要があります。 Parse および ToString メソッドを実装する方法の詳細と例については、「ユーザー定義型のコード化」を参照してください。
XML シリアル化
UDT は、XML シリアル化のコントラクトに準拠して、 xml データ型との間の変換をサポートする必要があります。 System.Xml.Serialization 名前空間には、オブジェクトを XML 形式のドキュメントまたはストリームにシリアル化するために使用されるクラスが含まれています。 XML シリアル化と逆シリアル化のカスタム書式設定を提供する IXmlSerializable インターフェイスを使用して、xml シリアル化を実装することができます。
XML シリアル化では、UDT から xml への明示的な変換を実行するだけでなく、次のことが可能になります。
xml データ型に変換した後、UDT インスタンスの値に対して Xquery を使用します。
SQL Server のネイティブ XML Web サービスを使用して、パラメーター化されたクエリと Web メソッドで UDT を使用します。
UDT を使用して、XML データの一括読み込みを受け取ることができます。
UDT 列を含むテーブルが格納されたデータセットをシリアル化できます。
UDT は、FOR XML クエリではシリアル化されません。 UDT の XML シリアル化を表示する FOR XML クエリを実行するには、SELECT ステートメントで各 UDT 列を xml データ型に明示的に変換します。 列を varbinary、 varchar、または nvarchar に明示的に変換することもできます。