ユーザー定義型の作成 - 要件

適用対象:SQL Server

Microsoft SQL Serverにインストールするユーザー定義型 (UDT) を作成するときは、いくつかの重要な設計上の決定を行う必要があります。 ほとんどの場合は、UDT を構造体として作成することをお勧めしますが、クラスとして作成することもできます。 UDT 定義を SQL Server に登録するには、UDT を作成するための仕様に準拠している必要があります。

UDT の実装要件

SQL Serverで実行するには、UDT 定義に次の要件を実装する必要があります。

UDT では 、Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute を指定する必要があります。 System.SerializableAttribute の使用は省略可能ですが、推奨されます。

  • UDT は、パブリック静的 (Microsoft Visual Basic では Shared) Null メソッドを作成して、クラスまたは構造体に System.Data.SqlTypes.INullable インターフェイスを実装する必要があります。 既定では、SQL Serverは null 対応です。 この作業は、UDT で実行されるコードが NULL 値を認識するために必要です。

  • UDT には、 からの解析をサポートするパブリック 静的 (または 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.IsByteOrderedfalse の場合、バイト順の比較は失敗します。

  • クラスで定義する UDT には、引数を受け取らないバプリック コンストラクターを含める必要があります。 必要に応じて、オーバーロードのクラス コンストラクターを追加作成できます。

  • UDT では、データ要素をパブリック フィールドまたはプロパティ プロシージャとして公開する必要があります。

  • パブリック名は 128 文字を超えることはできません。また、「データベース識別子」で定義されている識別子のSQL Server名前付け規則に準拠している必要があります。

  • sql_variant 列に UDT のインスタンスを含めることはできません。

  • SQL Server型システムは UDT 間の継承階層を認識していないため、継承されたメンバーには Transact-SQL からアクセスできません。 ただし、型のマネージド コード実装では、継承を使用してクラスを構造化したり、そのクラスのメソッドを呼び出すことができます。

  • クラス コンストラクター以外のメンバーはオーバーロードできません。 オーバーロードされたメソッドを作成した場合、アセンブリを登録したり、SQL Serverで型を作成したりしてもエラーは発生しません。 オーバーロード メソッドが検出されるのは、型の作成時ではなく実行時です。 オーバーロード メソッドは、呼び出されない限りクラス内に存在することができます。 エラーは、オーバーロード メソッドを呼び出した時点で発生します。

  • 静的 (または共有) メンバーは、定数または読み取り専用として宣言する必要があります。 静的メンバーを変更可能にすることはできません。

  • SqlUserDefinedTypeAttribute.MaxByteSize フィールドが -1 に設定されている場合、シリアル化された UDT は、ラージ オブジェクト (LOB) サイズ制限 (現在 2 GB) と同じ大きさにすることができます。 UDT のサイズは、 MaxByteSized フィールドで指定された値を超えることはできません。

注意

比較を実行するためにサーバーでは使用されませんが、必要に応じて、単一のメソッド CompareTo を公開する System.IComparable インターフェイスを実装できます。 このインターフェイスは、クライアント側で UDT 値を正確に比較したり並べ替える場合に使用します。

ネイティブ シリアル化

UDT に適したシリアル化属性は、作成する UDT の種類によって異なります。 ネイティブシリアル化形式では、SQL Serverが UDT の効率的なネイティブ表現をディスクに格納できるようにする非常に単純な構造が利用されます。 UDT が単純で、次の型のフィールドのみが含まれている場合は、 ネイティブ 形式をお勧めします。

boolbytesbyteshortushortintuintlongulongfloatdoubleSqlByteSqlInt16SqlInt32SqlInt64SqlDateTimeSqlSingleSqlDoubleSqlMoneySqlBoolean

上記の型のフィールドで構成される値型は、Visual C# の構造体 (Visual Basic では構造体) など、ネイティブ形式に適しています。 たとえば、ネイティブシリアル化形式で指定された UDT には、 ネイティブ 形式で指定された別の UDT の フィールドが含 まれている場合があります。 UDT 定義がより複雑で、上記のリストにないデータ型が含まれている場合は、代わりに UserDefined シリアル化形式を指定する必要があります。

ネイティブ形式には、次の要件があります。

  • この型では、 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize の値を指定しないでください。

  • すべてのフィールドがシリアル化可能である必要があります。

  • UDT が構造体ではなくクラスで定義されている場合は、 System.Runtime.InteropServices.StructLayoutAttributeStructLayout.LayoutKindSequential として指定する必要があります。 この属性は、データ フィールドの物理レイアウトを制御し、メンバーを出現順にレイアウトするために使用します。 SQL Serverでは、この属性を使用して、複数の値を持つ UDT のフィールド順序を決定します。

ネイティブ シリアル化で定義された UDT の例については、「コーディングUser-Defined型」の「Point UDT」を参照してください。

ユーザー定義シリアル化

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 属性の UserDefined 形式設定により、開発者はバイナリ形式を完全に制御できます。 Format 属性プロパティを UserDefined として指定する場合は、コードで次の操作を行う必要があります。

  • 省略可能な IsByteOrdered 属性プロパティを指定します。 既定値は false です。

  • Microsoft.SqlServer.Server.SqlUserDefinedTypeAttributeMaxByteSize プロパティを指定します。

  • System.Data.Sql.IBinarySerialize インターフェイスを実装して、UDT の Read メソッドと Write メソッドを実装するコードを記述します。

UserDefined シリアル化で定義された UDT の例については、「コーディングUser-Defined型」の「通貨 UDT」を参照してください。

注意

UDT フィールドをインデックス化するには、ネイティブ シリアル化を使用するか、UDT フィールドを保存する必要があります。

シリアル化属性

UDT のストレージ表現を構築し、クライアントに UDT を値として転送するためにシリアル化を使用する方法は、属性で決まります。 UDT の作成時に 、Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute を指定する必要があります。 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 属性は、クラスが UDT であることを示し、UDT のストレージを指定します。 必要に応じて Serializable 属性を指定できますが、SQL Serverはこれを必要としません。

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute には、次のプロパティがあります。

Format
UDT のデータ型に応じて、 シリアル 化形式 (Native または UserDefined) を指定します。

IsByteOrdered
UDT でバイナリ比較SQL Server実行する方法を決定するブール値。

IsFixedLength
この UDT のすべてのインスタンスの長さが同じであるかどうかを示します。

MaxByteSize
インスタンスのバイト単位の最大サイズ。 UserDefined シリアル化形式で MaxByteSize を指定する必要があります。 ユーザー定義シリアル化が指定された UDT の場合、 MaxByteSize は、ユーザーが定義したシリアル化された形式の UDT の合計サイズを参照します。 MaxByteSize の値は 1 ~ 8000 の範囲である必要があります。UDT が 8000 バイトを超えている (合計サイズが最大 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で比較操作を実行する場合、その結果は、マネージド コードで同じ比較操作が実行された場合と同じである必要があります。 IsByteOrderedtrue に設定されている場合は、次の機能もサポートされます。

  • この型の列にインデックスを作成する機能。

  • この型の列に CHECK 制約と UNIQUE 制約だけでなく主キーと外部キーを作成する機能。

  • Transact-SQL ORDER BY、GROUP BY、PARTITION BY 句を使用する機能。 これらの句を使用した場合、順序の決定には型のバイナリ表現が使用されます。

  • Transact-SQL ステートメントで比較演算子を使用する機能。

  • この型の計算列を保存する機能。

IsByteOrdered が true に設定されている場合、Native シリアル化形式と UserDefined シリアル化形式の両方で次の比較演算子がサポートされることに注意してください

  • 等しい (=)

  • 等しくない (!=)

  • より大きい (>)

  • より小さい (<)

  • 以上 (>=)

  • 以下 (<=)

NULL 値の許容属性の実装

アセンブリの属性を正しく指定することに加えて、クラスで NULL 値の許容属性をサポートする必要があります。 SQL Serverに読み込まれる UDT は null 対応ですが、UDT が null 値を認識するには、クラスで INullable インターフェイスを実装する必要があります。 UDT で null 許容を実装する方法の詳細と例については、「 User-Defined型のコーディング」を参照してください。

文字列の変換

UDT との間の文字列変換をサポートするには、 クラスに Parse メソッドと ToString メソッドを指定する必要があります。 Parse メソッドを使用すると、文字列を UDT に変換できます。 静的 (または Visual Basic では Shared) として宣言し、System.Data.SqlTypes.SqlString 型のパラメーターを受け取る必要があります。 Parse メソッドと ToString メソッドを実装する方法の詳細と例については、「User-Defined型のコーディング」を参照してください。

XML シリアル化

UDT では、XML シリアル化のコントラクトに準拠して 、xml データ型との間の変換をサポートする必要があります。 System.Xml。シリアル化名前空間には、オブジェクトを XML 形式のドキュメントまたはストリームにシリアル化するために使用されるクラスが含まれています。 XML シリアル化と逆シリアル化のカスタム書式を提供する IXmlSerializable インターフェイスを使用して、XML シリアル化を実装することを選択できます。

UDT から xml への明示的な変換を実行するだけでなく、XML シリアル化を使用すると、次のことが可能になります。

  • xml データ型への変換後、UDT インスタンスの値に対して Xquery を使用します。

  • パラメーター化されたクエリでは UDT を使用し、SQL Serverのネイティブ XML Web サービスでは Web メソッドを使用します。

  • UDT を使用して、XML データの一括読み込みを受け取ることができます。

  • UDT 列を含むテーブルが格納されたデータセットをシリアル化できます。

UDT は、FOR XML クエリではシリアル化されません。 UDT の XML シリアル化を表示する FOR XML クエリを実行するには、SELECT ステートメントで各 UDT 列を xml データ型に明示的に変換します。 列を varbinary、varchar、または nvarchar に明示的に変換することもできます。

参照

User-Defined型の作成