在 SQL Server Native Client 中使用使用者定義的類型

適用於: SQL Server Azure SQL Database Not supported. Azure Synapse Analytics Analytics Platform System (PDW)

重要

SQL Server Native Client (通常縮寫為 SNAC) 已從 SQL Server 2022 (16.x) 和 SQL Server Management Studio 19 (SSMS) 中移除。 不建議使用 SQL Server Native Client (SQLNCLI 或 SQLNCLI11) 和舊版 Microsoft OLE DB Provider for SQL Server (SQLOLEDB) 開發新的應用程式。 往後請改用新的 Microsoft OLE DB Driver (MSOLEDBSQL) for SQL Server 或最新的 Microsoft ODBC Driver for SQL Server。 如需作為 SQL Server 資料庫引擎 元件隨附的 SQLNCLI(版本 2012 到 2019),請參閱此支援生命週期例外狀況

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 函數或預存程序的引數。

SQL Server Native Client OLE DB 提供者

SQL Server Native Client OLE DB 提供者支援 UDT 做為具有元數據資訊的二進位類型,這可讓您將 UDT 當做對象來管理。 UDT 資料行會公開為 DBTYPE_UDT,而且它們的中繼資料會透過核心 OLE DB 介面 IColumnRowset 和新的 ISSCommandWithParameters 介面來公開。

注意

IRowsetFind::FindNextRow 方法無法與 UDT 資料類型一起運作。 如果將 UDT 當做搜尋資料行類型使用,就會傳回 DB_E_BADCOMPAREOP。

資料繫結和強制型轉

下列資料表描述當搭配 SQL Server UDT 使用列出的資料類型時,所發生的繫結與強制型轉。 UDT 資料行會透過 SQL Server Native Client OLE DB 提供者公開為 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 資料列集的加入和變更

SQL Server Native Client 會將新的值或變更新增至許多核心 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 結構描述資料列集

SQL Server Native Client OLE DB 提供者會公開描述已註冊 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 結構描述資料列集

SQL Server Native Client OLE DB 提供者會公開新的提供者特定架構數據列集,描述指定伺服器的元件相依性。 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 結構描述資料列集

SQL Server Native Client OLE DB 提供者會公開新的架構數據列集,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 屬性集的加入和變更

SQL Server Native Client 會將新的值或變更新增至許多核心 OLE DB 屬性集。

DBPROPSET_SQLSERVERPARAMETER 屬性集

為了透過 OLE DB 支援 UDT,SQL Server Native Client 會實作新的 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 介面中建立數據表,SQL Server Native Client 會將下列三個新數據行新增至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 介面的加入和變更

SQL Server Native Client 會將新的值或變更新增至許多核心 OLE DB 介面。

ISSCommandWithParameters 介面

為了透過 OLE DB 支援 UDT,SQL Server Native Client 會實作一些變更,包括新增 ISSCommandWithParameters 介面。 這個新的介面繼承自核心的 OLE DB 介面 ICommandWithParameters。 除了繼承自 ICommandWithParameters 的三種方法之外;GetParameterInfoMapParameterNamesSetParameterInfo; ISSCommandWithParameters 提供用來處理伺服器特定數據類型的 GetParameterProperties 和 SetParameterProperties 方法。

注意

ISSCommandWithParameters 介面也會使用新的 SSPARAMPROPS 結構。

IColumnsRowset 介面

除了 ISSCommandWithParameters 介面之外,SQL Server Native Client 也會將新值新增至呼叫 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 資料行與其他二進位類型區分為DBTYPE_UDT,方法是查看上面指定的新增 UDT 元數據。 如果該資料有一部分是完整的,伺服器類型會是 UDT。 如果不是 UDT 伺服器類型,這些資料行一定會當做 NULL 傳回。

SQL Server Native Client ODBC Driver

SQL Server Native Client ODBC 驅動程式中已進行多項變更,以支援 UDT。 SQL Server Native Client ODBC 驅動程式會將 SQL Server UDT 對應至SQL_SS_UDT驅動程式特定的 SQL 數據類型識別符。 UDT 資料行會顯示為SQL_SS_UDT。 如果您使用 UDT 的 ToString 或 ToXMLString 方法,或透過 CAST/CONVERT 函式,明確將 UDT 數據行對應至 SQL 語句中的另一個類型,結果集中的數據行類型會反映數據行已轉換成的實際類型

SQLColAttribute、SQLDescribeParam、SQLGetDescField

已新增四個新的驅動程式特定描述元字段,以提供結果集的 UDT 數據行或預存程式/參數化查詢的 UDT 參數,以透過 SQLColAttribute、SQLDescribeParamSQLGetDescField 函式擷取的其他資訊。

已新增的四個新的描述元字段是SQL_CA_SS_UDT_CATALOG_NAME、SQL_CA_SS_UDT_SCHEMA_NAME、SQL_CA_SS_UDT_TYPE_NAME和SQL_CA_SS_UDT_ASSEMBLY_TYPE_NAME。

SQLColumns、SQLProcedureColumns

此外,會將三個新的驅動程式特定數據行新增至從 SQLColumns 和 SQLProcedureColumns 函式傳回的結果集,以提供 UDT 結果集數據行或 UDT 參數的其他資訊。 這三個新數據行是SS_UDT_CATALOG_NAME、SS_UDT_SCHEMA_NAME和SS_UDT_ASSEMBLY_TYPE_NAME。

支援的轉換

從 SQL 轉換成 C 數據類型時,SQL_C_WCHAR、SQL_C_BINARY和SQL_C_CHAR全都可以轉換成SQL_SS_UDT。 不過請注意,從 SQL_C_WCHAR 和 SQL_C_CHAR SQL 數據類型轉換時,二進位數據會轉換成十六進位字串。

從 C 轉換成 SQL 資料類型時,SQL_C_WCHAR、SQL_C_BINARY和SQL_C_CHAR全都可以轉換成SQL_SS_UDT。 不過請注意,從 SQL_C_WCHAR 和 SQL_C_CHAR SQL 數據類型轉換時,二進位數據會轉換成十六進位字串。

另請參閱

SQL Server Native Client 功能
ISSCommandWithParameters (OLE DB)