建立使用者定義型別 - 需求

適用於:SQL Server

建立要安裝在 Microsoft SQL Server 中的使用者定義類型 (UDT) 時,您必須做出幾項重要的設計決策。 對於大部分的 UDT 而言,雖然將 UDT 當做類別來建立也是一種選擇,但是建議將 UDT 當做結構來建立。 UDT 定義必須符合建立 UDT 的規格,才能向 SQL Server 註冊。

實作 UDT 的需求

若要在 SQL Server 中執行,您的 UDT 必須在 UDT 定義中實作下列需求:

UDT 必須指定 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttributeSystem.SerializableAttribute的使用是選擇性的,但建議使用。

  • UDT 必須在 類別或結構中實作 System.Data.SqlTypes.INullable 介面,方法是在 Microsoft Visual Basic 中建立公用 靜態 (Shared) Null 方法。 SQL Server預設為 null 感知。 若要讓在 UDT 中執行的程式碼能夠辨識 Null 值,此為必要選項。

  • UDT 必須包含可支援剖析來源的公用 靜態 (或 Shared) Parse 方法,以及用來轉換成物件的字串表示的公用 ToString 方法。

  • 具有使用者定義序列化格式的 UDT 必須實作 System.Data.IBinarySerialize 介面,並提供 讀取寫入 方法。

  • UDT 必須實 作System.Xml。如果需要覆寫標準序列化,Serialization.IXmlSerializable或所有公用欄位和屬性都必須是 XML 可序列化或以 XmlIgnore 屬性裝飾的類型。

  • 一個 UDT 物件必須僅有一個序列化。 如果序列化或還原序列化常式識別一個以上的特定物件表示法,則驗證會失敗。

  • SqlUserDefinedTypeAttribute.IsByteOrdered 必須為 true ,才能依位元組順序比較資料。 如果未實作 IComparable 介面,而且 SqlUserDefinedTypeAttribute.IsByteOrderedfalse,位元組順序比較將會失敗。

  • 以類別定義的 UDT 必須具有不使用引數的公用建構函式。 您可以選擇性地建立其他多載類別建構函式。

  • UDT 必須將資料元素公開為公用欄位或屬性程序。

  • 公用名稱不能超過 128 個字元,而且必須符合資料庫識別碼中所定義的識別碼SQL Server命名規則。

  • SQL_variant 資料行不能包含 UDT 的實例。

  • 無法從 Transact-SQL 存取繼承成員,因為SQL Server類型系統不知道 UDT 之間的繼承階層。 不過,結構化類別時可以使用繼承,並可以在型別的 Managed 程式碼實作中呼叫此類方法。

  • 成員不可多載,但類別建構函式除外。 如果您確實建立多載方法,當您註冊元件或在 SQL Server 中建立類型時,不會引發任何錯誤。 多載方法的偵測會於執行階段發生,而不是在建立類型時發生。 在叫用之前,多載方法會一直存在於類別中。 一旦叫用多載方法,將會引發錯誤。

  • 任何 靜態 (或 共用) 成員都必須宣告為常數或唯讀。 靜態成員無法時常變動。

  • 如果 SqlUserDefinedTypeAttribute.MaxByteSize 欄位設定為 -1,則序列化的 UDT 可以和目前 2 GB) (LOB) 大物件的大小 (限制一樣大。 UDT 的大小不能超過 MaxByteSized 欄位中指定的值。

注意

雖然伺服器不會使用它來執行比較,但您可以選擇性地實作 System.IComparable 介面,這會公開單一方法 CompareTo。 在需要對 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.StructLayoutAttribute 必須指定為 StructLayout.LayoutKindSequential ,而不是結構。 此屬性可以控制資料欄位的實體配置,並用於強制以成員出現的順序對成員進行配置。 SQL Server使用此屬性來判斷具有多個值的 UDT 欄位順序。

如需使用 原生 序列化定義的 UDT 範例,請參閱 編碼User-Defined類型的Point UDT。

UserDefined 序列化

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute屬性的UserDefined格式設定可讓開發人員完全控制二進位格式。 將 Format 屬性屬性指定為 UserDefined時,您必須在程式碼中執行下列動作:

  • 指定選擇性 的 IsByteOrdered 屬性。 預設值為 false

  • 指定Microsoft.SqlServer.Server.SqlUserDefinedTypeAttributeMaxByteSize屬性。

  • 撰寫程式碼以實作System.Data.Sql.IBinarySerialize介面,以實作 UDT 的讀取寫入方法。

如需以 UserDefined 序列化定義的 UDT 範例,請參閱 編碼User-Defined類型的貨幣 UDT。

注意

UDT 欄位必須使用原生序列化,或保存下來進行索引。

序列化屬性

屬性會決定如何使用序列化來建構 UDT 的儲存表示,並將 UDT 以傳值方式傳輸到用戶端。 建立 UDT 時,您必須指定 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttributeMicrosoft.SqlServer.Server.SqlUserDefinedTypeAttribute屬性工作表示類別是 UDT,並指定 UDT 的儲存體。 您可以選擇性地指定Serializable屬性,不過SQL Server不需要這個屬性。

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute具有下列屬性。

格式
根據 UDT 的資料類型,指定可以是 NativeUserDefined的序列化格式。

IsByteOrdered
布林值,決定SQL Server如何在 UDT 上執行二進位比較。

IsFixedLength
表示此 UDT 的所有執行個體是否為相同長度。

MaxByteSize
執行個體的大小最大值 (位元組)。 您必須使用UserDefined序列化格式來指定MaxByteSize。 針對指定使用者定義序列化的 UDT, MaxByteSize 會參考使用者所定義之序列化形式中 UDT 的總大小。 MaxByteSize的值必須介於 1 到 8000 的範圍內,或設定為 -1,表示 UDT 大於 8000 個位元組, (總大小不能超過 LOB 大小上限) 。 請考慮具有 10 個字元之字串的 UDT, (System.Char) 。 當 UDT 使用 BinaryWriter 序列化時,序列化字串的總大小是 UDT 個位元組:每個 Unicode 2-16 字元兩個位元組,乘以字元的最大數目,再加上序列化二進位資料流所造成的兩個控制位元組負擔。 因此,在判斷 MaxByteSize的值時,必須考慮序列化 UDT 的總大小:二進位格式序列化的資料大小加上序列化所產生的額外負荷。

ValidationMethodName
用於驗證 UDT 執行個體之方法的名稱。

設定 IsByteOrdered

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered 屬性設定為 true時,您實際上會保證序列化二進位資料可用於資訊的語意排序。 因此,每個位元組排序的 UDT 物件執行個體只能有一個序列化表示法。 在序列化位元組的SQL Server中執行比較作業時,其結果應該與在 Managed 程式碼中執行相同的比較作業相同。 當 IsByteOrdered設定為true時,也支援下列功能:

  • 在此型別之資料行上建立索引的功能。

  • 在此類型的資料行上建立主索引鍵及外部索引鍵,以及建立 CHECK 條件約束及 UNIQUE 條件約束的功能。

  • 能夠使用 Transact-SQL ORDER BY、GROUP BY 和 PARTITION BY 子句。 在這些情況下,類型的二進位表示法用於決定順序。

  • 在 Transact-SQL 語句中使用比較運算子的能力。

  • 保留此類型之計算資料行的功能。

請注意,當IsByteOrdered設定為true時,NativeUserDefined序列化格式都支援下列比較運算子:

  • 等於 (=)

  • 不等於 (!=)

  • 大於 (>)

  • 小於 (<)

  • 大於或等於 (> =)

  • 小於或等於 (< =)

實作 Null 屬性

除了必須正確地指定組件的屬性外,您的類別還必須能夠支援 Null 屬性。 載入SQL Server的 UDT 是 null 感知的,但為了讓 UDT 辨識 Null 值,類別必須實作INullable介面。 如需如何在 UDT 中實作可為 Null 性的詳細資訊和範例,請參閱 編碼User-Defined類型

字串轉換

若要支援 UDT 的字串轉換,您必須在類別中提供 Parse 方法和 ToString 方法。 Parse方法可讓字串轉換成 UDT。 它必須在 Visual Basic) 中宣告為 靜態 (或 共用 ,並採用 System.Data.SqlTypes.SqlString類型的參數。 如需如何實作 ParseToString 方法的詳細資訊和範例,請參閱 撰寫程式碼User-Defined類型

XML 序列化

UDT 必須符合 XML 序列化的合約,以支援從 xml 資料類型轉換。 System.Xml。序列化命名空間包含用來將物件序列化為 XML 格式檔或資料流程的類別。 您可以選擇使用IXmlSerializable介面來實作xml序列化,以提供 XML 序列化和還原序列化的自訂格式。

除了執行從 UDT 到 xml的明確轉換之外,XML 序列化還可讓您:

  • 在轉換成xml資料類型之後,在 UDT 實例的值上使用Xquery

  • 在參數化查詢和 Web 方法中使用 UDT 搭配 SQL Server 中的原生 XML Web 服務。

  • 使用 UDT 接收 XML 資料的大量載入。

  • 序列化包含具有 UDT 資料行之資料表的 DataSet。

在 FOR XML 查詢中不會序列化 UDT。 若要執行顯示 UDT 之 XML 序列化的 FOR XML 查詢,請明確地將每個 UDT 資料行轉換成 SELECT 語句中的 xml 資料類型。 您也可以明確地將資料行轉換成Varbinary、VarcharNvarchar

另請參閱

建立User-Defined類型