共用方式為


建立使用者定義類型 – 需求

適用於:SQL Server

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

實作UDT的需求

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

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

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

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

  • 具有使用者定義串行化格式的 UDT 必須實 作 System.Data.IBinarySerialize 介面,並提供 ReadWrite 方法。

  • 如果需要覆寫標準串行化,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 可以和大型物件 (LOB) 大小限制 (目前為 2 GB) 一樣大。 UDT 的大小不能超過 MaxByteSized 字段中指定的值。

注意

雖然伺服器不會使用它來執行比較,但您可以選擇性地實 作 System.IComparable 介面,這會公開單一方法 CompareTo。 在想要正確地比較或排序 UDT 值的情況下,這會在用戶端上使用。

原生串行化

為您的 UDT 選擇正確的串行化屬性,取決於您嘗試建立的 UDT 類型。 原生串行化格式會利用非常簡單的結構,讓 SQL Server 在磁碟上儲存 UDT 的有效原生表示法。 如果 UDT 很簡單,且只包含下列類型的欄位,建議使用原生格式:

boolbyte、sbyteshortushortint、uintlongulong、floatdouble、SqlByteSqlInt16、SqlInt32、SqlInt64、SqlDateTime、SqlSingleSqlDoubleSqlMoneySqlBoolean

由上述類型欄位組成的實值型別是原生格式的良好候選專案,例如 Visual C# 中的結構(或 Visual Basic 中已知的結構)。 例如,以原生串行化格式指定的 UDT 可能包含另一個以原生格式指定之 UDT 的欄位。 如果 UDT 定義比較複雜,而且包含不在上述清單上的資料類型,您必須改為指定 UserDefined 串行化格式。

原生格式具有下列需求:

  • 此類型不得指定 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize 的值。

  • 所有欄位都必須可串行化。

  • 如果 UDT 是在類別中定義,則必須將 System.Runtime.InteropServices.StructLayoutAttribute 指定為 StructLayout.LayoutKindSequential,而不是結構。 這個屬性會控制數據欄位的實體配置,並用來強制根據成員出現的順序進行配置。 SQL Server 會使用這個屬性來判斷具有多個值的 UDT 字段順序。

如需使用原生串行化定義的 UDT 範例,請參閱撰寫使用者定義型別中的點 UDT。

使用者定義串行化

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

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

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

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

如需以 UserDefined 串行化定義的 UDT 範例,請參閱撰寫使用者定義型別中的貨幣 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)。 使用 BinaryWriter 串行化 UDT 時,串行化字串的總大小為 22 個字節:每個 Unicode UTF-16 字元 2 個字節,乘以最大字元數,加上串行化二進位數據流所產生的額外負荷 2 個控制位元組。 因此,判斷 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 串行化格式都支援下列比較運算符:

  • 等於 (=)

  • 不等於 (!=)

  • 大於 (>)

  • 小於 (<)

  • 大於或等於 (>=)

  • 小於或等於 (<=)

實作 Nullability

除了正確指定元件的屬性之外,您的類別也必須支援可為 Null。 載入 SQL Server 的 UDT 是 Null 感知,但為了讓 UDT 辨識 Null 值,類別必須實 作 INullable 介面。 如需如何在 UDT 中實作可為 Null 的詳細資訊和範例,請參閱 撰寫使用者定義型別程式代碼。

字串轉換

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

XML 序列化

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

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

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

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

  • 使用UDT接收大量 XML 數據負載。

  • 串行化包含具有UDT資料行之數據表的數據集。

UDT 不會在 FOR XML 查詢中串行化。 若要執行顯示 UDT XML 串行化的 FOR XML 查詢,請明確將每個 UDT 資料行轉換成 SELECT 語句中的 xml 數據類型。 您也可以明確地將數據行轉換成 varbinaryvarchar 或 nvarchar

另請參閱

建立使用者定義類型