使用使用者定義型別
適用於:SQL Server Azure SQL 資料 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics Platform System (PDW)
SQL Server 2005 (9.x) 引進使用者定義型別 (UDT)。 UDT 會擴充 SQL 類型系統,其方式是允許您將物件與自訂資料結構儲存在 SQL Server 資料庫中。 UDT 可以包含多個資料類型並可以具有行為,使其有別於由單一 SQL Server 系統資料類型組成的傳統別名資料類型。 UDT 是使用會產生可驗證程式碼之 .NET Common Language Runtime (CLR) 支援的任何語言所定義。 這包括 C# 和 Visual Basic .NET。 資料會公開為 .NET 類別或結構的欄位及屬性,並且其行為是由類別或結構的方法來定義。
UDT 可以用作資料表的資料行定義、Transact-SQL 批次中的變數,或者 Transact-SQL 函數或預存程序的引數。
OLE DB Driver for SQL Server
OLE DB Driver for SQL Server 支援使用 UDT 當作具有中繼資料資訊的二進位類型,好讓您可以將 UDT 當作物件來管理。 UDT 資料行會公開為 DBTYPE_UDT,而且它們的中繼資料會透過核心 OLE DB 介面 IColumnRowset 和新的 ISSCommandWithParameters 介面來公開。
注意
IRowsetFind::FindNextRow 方法無法與 UDT 資料類型一起運作。 如果將 UDT 當做搜尋資料行類型使用,就會傳回 DB_E_BADCOMPAREOP。
資料繫結和強制型轉
下列資料表描述當搭配 SQL Server UDT 使用列出的資料類型時,所發生的繫結與強制型轉。 UDT 資料行是透過 OLE DB Driver for SQL Server (當作 DBTYPE_UDT) 公開的。 您可以透過適當的結構描述資料列集來取得中繼資料,好讓您可以將自己定義的類型當做物件來管理。
資料類型 | 到伺服器 UDT |
到伺服器 非 UDT |
從伺服器 UDT |
從伺服器 非 UDT |
---|---|---|---|---|
DBTYPE_UDT | 支援6 | 錯誤1 | 支援6 | 錯誤5 |
DBTYPE_BYTES | 支援6 | N/A2 | 支援6 | N/A2 |
DBTYPE_WSTR | 支援3、6 | N/A2 | 支援4、6 | N/A2 |
DBTYPE_BSTR | 支援3、6 | N/A2 | 支援4 | N/A2 |
DBTYPE_STR | 支援3、6 | N/A2 | 支援4、6 | N/A2 |
DBTYPE_IUNKNOWN | 不支援 | N/A2 | 不支援 | N/A2 |
DBTYPE_VARIANT (VT_UI1 | VT_ARRAY) | 支援6 | N/A2 | 支援4 | N/A2 |
DBTYPE_VARIANT (VT_BSTR) | 支援3、6 | N/A2 | N/A | N/A2 |
1如果使用 ICommandWithParameters::SetParameterInfo 指定 DBTYPE_UDT 以外的伺服器類型,而且存取子類型為 DBTYPE_UDT,則當執行陳述式時會發生錯誤 (DB_E_ERRORSOCCURRED;參數狀態為 DBSTATUS_E_BADACCESSOR)。 否則資料會傳給伺服器,但是伺服器會傳回一則錯誤,指示從 UDT 到參數的資料類型之間沒有隱含轉換。
2 超出本文的範圍。
3 發生從十六進位字串轉換為二進位資料的資料轉換。
4 發生從二進位資料轉換為十六進位字串的資料轉換。
5建立存取子或提取時可能發生驗證,錯誤為 DB_E_ERRORSOCCURRED,繫結狀態設定為 DBBINDSTATUS_UNSUPPORTEDCONVERSION。
6可能會使用 BY_REF。
可以繫結 DBTYPE_NULL 和 DBTYPE_EMPTY 用於輸入參數,但是不能用於輸出參數或結果。 當針對輸入參數來繫結時,狀態必須設定為 DBSTATUS_S_ISNULL 或 DBSTATUS_S_DEFAULT。
DBTYPE_UDT 也可以轉換成 DBTYPE_EMPTY 和 DBTYPE_NULL,但是 DBTYPE_NULL 和 DBTYPE_EMPTY 無法轉換成 DBTYPE_UDT。 這與 DBTYPE_BYTES 一致。
注意
可使用新的介面將 UDT 當作參數 ISSCommandWithParameters 處理 (該參數繼承自 ICommandWithParameters)。 應用程式必須使用這個介面,至少為 UDT 參數設定 DBPROPSET_SQLSERVERPARAMETER 屬性集的 SSPROP_PARAM_UDT_NAME。 如果未進行這項處理,ICommand::Execute 將會傳回 DB_E_ERRORSOCCURRED。 本文稍後將描述這個介面和屬性集。
如果使用者定義型別插入資料行中,而該資料行不夠大,因此無法保存它的所有資料,則 ICommand::Execute 將會傳回 S_OK,而且狀態為 DB_E_ERRORSOCCURRED。
OLE DB 核心服務 (IDataConvert) 提供的資料轉換不適用於 DBTYPE_UDT。 不支援其他任何繫結。
OLE DB 資料列集的加入和變更
OLE DB Driver for SQL Server 會將新的值或變更加入到許多核心 OLE DB 結構描述資料列集。
PROCEDURE_PARAMETERS 結構描述資料列集
下列是已經針對 PROCEDURE_PARAMETERS 結構描述資料列集所做的加入。
資料行名稱 | 類型 | 描述 |
---|---|---|
SS_UDT_CATALOGNAME | DBTYPE_WSTR | 三部分名稱的識別碼。 |
SS_UDT_SCHEMANAME | DBTYPE_WSTR | 三部分名稱的識別碼。 |
SS_UDT_NAME | DBTYPE_WSTR | 三部分名稱的識別碼。 |
SS_UDT_ASSEMBLY_TYPENAME | DBTYPE_WSTR | 組件限定名稱,其中包含類型名稱以及要由 CLR 參考所需的所有組件識別。 |
SQL_ASSEMBLIES 結構描述資料列集
OLE DB Driver for SQL Server 會公開新的提供者特定的結構描述資料列集,以描述已註冊的 UDT。 ASSEMBLY 伺服器可指定為 DBTYPE_WSTR,但是不在資料列集內。 如果未指定的話,此資料列集將預設為目前的伺服器。 下表定義 SQL_ASSEMBLIES 結構描述資料列集:
資料行名稱 | 類型 | 描述 |
---|---|---|
ASSEMBLY_CATALOG | DBTYPE_WSTR | 包含該類型之組件的目錄名稱。 |
ASSEMBLY_SCHEMA | DBTYPE_WSTR | 包含該類型之組件的結構描述名稱或擁有者名稱。 雖然組件是由資料庫指定範圍,而不是由結構描述指定範圍,組件依然有擁有者 (這裡有反映這一點)。 |
ASSEMBLY_NAME | DBTYPE_WSTR | 包含該類型的組件名稱。 |
ASSEMBLY_ID | DBTYPE_UI4 | 包含該類型之組件的物件識別碼。 |
PERMISSION_SET | DBTYPE_WSTR | 表示組件之存取範圍的值。 值包括 "SAFE"、"EXTERNAL_ACCESS" 和 "UNSAFE"。 |
ASSEMBLY_BINARY | DBTYPE_BYTES | 組件的二進位表示法。 |
SQL_ASSEMBLIES_ DEPENDENCIES 結構描述資料列集
OLE DB Driver for SQL Server 會公開新的提供者特定的結構描述資料列集,以描述指定之伺服器的組件相依性。 ASSEMBLY_SERVER 可由呼叫端指定為 DBTYPE_WSTR,但是不在資料列集內。 如果未指定的話,此資料列集將預設為目前的伺服器。 下表定義 SQL_ASSEMBLY_DEPENDENCIES 結構描述資料列集:
資料行名稱 | 類型 | 描述 |
---|---|---|
ASSEMBLY_CATALOG | DBTYPE_WSTR | 包含該類型之組件的目錄名稱。 |
ASSEMBLY_SCHEMA | DBTYPE_WSTR | 包含該類型之組件的結構描述名稱或擁有者名稱。 雖然組件是由資料庫指定範圍,而不是由結構描述指定範圍,組件依然有擁有者 (這裡有反映這一點)。 |
ASSEMBLY_ID | DBTYPE_UI4 | 組件的物件識別碼。 |
REFERENCED_ASSEMBLY_ID | DBTYPE_UI4 | 參考之組件的物件識別碼。 |
SQL_USER_TYPES 結構描述資料列集
OLE DB Driver for SQL Server 會公開新的結構描述資料列集 SQL_USER_TYPES,以描述何時新增指定之伺服器的已註冊 UDT。 UDT_SERVER 必須由呼叫端指定為 DBTYPE_WSTR,但是不在資料列集內。 下表定義了 SQL_USER_TYPES 結構描述資料列集。
資料行名稱 | 類型 | 描述 |
---|---|---|
UDT_CATALOGNAME | DBTYPE_WSTR | 如果是 UDT 資料行,這個屬性就是指定 UDT 定義所在之目錄名稱的字串。 |
UDT_SCHEMANAME | DBTYPE_WSTR | 如果是 UDT 資料行,這個屬性就是指定 UDT 定義所在之結構描述名稱的字串。 |
UDT_NAME | DBTYPE_WSTR | 包含 UDT 類別的組件名稱。 |
UDT_ASSEMBLY_TYPENAME | DBTYPE_WSTR | 完整類型名稱 (AQN) 包含前面有加上命名空間的類型名稱 (適用的話)。 |
COLUMNS 結構描述資料列集
COLUMNS 結構描述資料列集的新增項目包含下列資料行:
資料行名稱 | 類型 | 描述 |
---|---|---|
SS_UDT_CATALOGNAME | DBTYPE_WSTR | 如果是 UDT 資料行,這個屬性就是指定 UDT 定義所在之目錄名稱的字串。 |
SS_UDT_SCHEMANAME | DBTYPE_WSTR | 如果是 UDT 資料行,這個屬性就是指定 UDT 定義所在之結構描述名稱的字串。 |
SS_UDT_NAME | DBTYPE_WSTR | UDT 的名稱 |
SS_UDT_ASSEMBLY_TYPENAME | DBTYPE_WSTR | 完整類型名稱 (AQN) 包含前面有加上命名空間的類型名稱 (適用的話)。 |
OLE DB 屬性集的加入和變更
OLE DB Driver for SQL Server 會將新的值或變更加入到許多核心 OLE DB 屬性集。
DBPROPSET_SQLSERVERPARAMETER 屬性集
為了透過 OLE DB 支援 UDT,OLE DB Driver for SQL Server 會實作新的 DBPROPSET_SQLSERVERPARAMETER 屬性集,其中包含以下值:
名稱 | 類型 | 描述 |
---|---|---|
SSPROP_PARAM_UDT_CATALOGNAME | DBTYPE_WSTR | 三部分名稱的識別碼。 如果是 UDT 參數,這個屬性就是指定使用者定義型別定義所在之目錄名稱的字串。 |
SSPROP_PARAM_UDT_SCHEMANAME | DBTYPE_WSTR | 三部分名稱的識別碼。 如果是 UDT 參數,這個屬性就是指定使用者定義型別定義所在之結構描述名稱的字串。 |
SSPROP_PARAM_UDT_NAME | DBTYPE_WSTR | 三部分名稱的識別碼。 如果是 UDT 資料行,這個屬性就是指定使用者定義型別之單一部分名稱的字串。 |
SSPROP_PARAM_UDT_NAME 為強制性。 SSPROP_PARAM_UDT_CATALOGNAME 和 SSPROP_PARAM_UDT_SCHEMANAME 是選擇性。 如果未正確指定任何屬性,將會傳回 DB_E_ERRORSINCOMMAND。 如果 SSPROP_PARAM_UDT_CATALOGNAME 和 SSPROP_PARAM_UDT_SCHEMANAME 皆未指定,則 UDT 必須定義在與資料表相同的資料庫和結構描述中。 如果 UDT 定義不在與資料表相同的結構描述中 (但是在相同資料庫內),則必須指定 SSPROP_PARAM_UDT_SCHEMANAME。 如果 UDT 定義位於不同的資料庫內,則必須指定 SSPROP_PARAM_UDT_CATALOGNAME 和 SSPROP_PARAM_UDT_SCHEMANAME 這兩者。
DBPROPSET_SQLSERVERCOLUMN 屬性集
為了支援 ITableDefinition 介面中的資料表建立,OLE DB Driver for SQL Server 會將下列三個新的資料行新增到 DBPROPSET_SQLSERVERCOLUMN 屬性集。
名稱 | 描述 | 類型 | 描述 |
---|---|---|---|
SSPROP_COL_UDT_CATALOGNAME | UDT_CATALOGNAME | VT_BSTR | 如果是 DBTYPE_UDT 類型的資料行,這個屬性就是指定 UDT 定義所在之目錄名稱的字串。 |
SSPROP_COL_UDT_SCHEMANAME | UDT_SCHEMANAME | VT_BSTR | 如果是 DBTYPE_UDT 類型的資料行,這個屬性就是指定 UDT 定義所在之結構描述名稱的字串。 |
SSPROP_COL_UDT_NAME | UDT_NAME | VT_BSTR | 如果是 DBTYPE_UDT 類型的資料行,這個屬性就是指定 UDT 之單一部分名稱的字串。 如果是其他資料行類型,這個屬性會傳回空字串。 |
注意
UDT 不會出現在 PROVIDER_TYPES 結構描述資料列集中。 所有資料行都有讀取和寫入存取權。
ADO 將會使用描述欄中的對應項目來參考這些屬性。
SSPROP_COL_UDTNAME 是強制性。 SSPROP_COL_UDT_CATALOGNAME 和 SSPROP_COL_UDT_SCHEMANAME 是選擇性。 如果未正確指定任何屬性,將會傳回 DB_E_ERRORSINCOMMAND。
如果 SSPROP_COL_UDT_CATALOGNAME 或 SSPROP_COL_UDT_SCHEMANAME 皆未指定,則 UDT 必須定義在與資料表相同的資料庫和結構描述中。
如果 UDT 定義不在與資料表相同的結構描述中 (但是在相同資料庫內),則必須指定 SSPROP_COL_UDT_SCHEMANAME。
如果 UDT 定義位於不同的資料庫內,則必須指定 SSPROP_COL_UDT_CATALOGNAME 和 SSPROP_COL_UDT_SCHEMANAME 這兩者。
OLE DB 介面的加入和變更
OLE DB Driver for SQL Server 會將新的值或變更加入到許多核心 OLE DB 介面。
ISSCommandWithParameters 介面
為了透過 OLE DB 支援 UDT,OLE DB Driver for SQL Server 會實作一些變更,其中包括新增 ISSCommandWithParameters 介面。 這個新的介面繼承自核心的 OLE DB 介面 ICommandWithParameters。 除了繼承自 ICommandWithParameters 的三種方法 (GetParameterInfo、MapParameterNames 和 SetParameterInfo),ISSCommandWithParameters 也提供用來處理伺服器特定資料類型的 GetParameterProperties 和 SetParameterProperties 方法。
注意
ISSCommandWithParameters 介面也會使用新的 SSPARAMPROPS 結構。
IColumnsRowset 介面
除了 ISSCommandWithParameters 介面以外,OLE DB Driver for SQL Server 也在透過 IColumnsRowset::GetColumnRowset 方法呼叫而傳回的資料列集內新增值,包括以下項目。
資料行名稱 | 類型 | 描述 |
---|---|---|
DBCOLUMN_SS_UDT_CATALOGNAME | DBTYPE_WSTR | UDT 目錄名稱識別碼。 |
DBCOLUMN_SS_UDT_SCHEMANAME | DBTYPE_WSTR | UDT 結構描述名稱識別碼。 |
DBCOLUMN_SS_UDT_NAME | DBTYPE_WSTR | UDT 名稱識別碼。 |
DBCOLUMN_SS_ASSEMBLY_TYPENAME | DBTYPE_WSTR | 組件限定名稱,其中包含類型名稱以及要由 CLR 參考所需的所有組件識別。 |
當 DBCOLUMN_TYPE 設定為 DBTYPE_UDT 時,您可以查看上面指定的新增 UDT 中繼資料,讓伺服器 UDT 資料行與二進位類型差異化。 如果該資料有一部分是完整的,伺服器類型會是 UDT。 如果不是 UDT 伺服器類型,這些資料行一定會當做 NULL 傳回。
另請參閱
OLE DB Driver for SQL Server 功能
ISSCommandWithParameters (OLE DB)