value() 方法(xml 資料類型)
適用於:SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體
對 XML 執行 XQuery,並傳回 SQL 類型的值。 此方法會傳回純量值。
通常您會使用此方法,從儲存在 xml 類型資料行、參數或變數中的 XML 執行個體擷取值。 如此一來,您可以指定 SELECT
結合或比較 XML 資料與非 XML 資料行中資料的查詢。
語法
value ( XQuery , SQLType )
引數
XQuery
XQuery 表達式是字串常值,可擷取 XML 實例內的數據。 XQuery 最多只能傳回一個值。 否則,就會傳回錯誤。
SQLType
要傳回的慣用 SQL 類型,字串常值。 此方法的傳回類型符合 SQLType 參數。 SQLType 可以是使用者定義的 SQL 資料類型。
注意
SQLType 不能是下列其中一種數據類型:xml、image、text、ntext、sql_variant或 Common Language Runtime (CLR) 使用者定義型別。
方法會 value()
隱含使用 Transact-SQL CONVERT
運算符。 value()
會嘗試將 XQuery 運算式的結果、串行化的字串表示,從 XML 架構定義 (XSD) 類型轉換為 Transact-SQL 轉換所指定的對應 SQL 類型。 如需 類型轉換規則 CONVERT
的詳細資訊,請參閱 CAST 和 CONVERT。
基於效能考慮,您可以搭配 使用 exist()
, sql:column()
而不是 value()
在述詞中使用 方法,以與關係型值進行比較。 本文稍後會顯示此 exist()
範例。
範例
本文 Transact-SQL 程式碼範例使用 AdventureWorks2022
或 AdventureWorksDW2022
範例資料庫,從 Microsoft SQL Server Samples 和 Community Projects (Microsoft SQL Server 範例和社群專案)首頁即可下載。
A. 針對 XML 類型變數使用 value() 方法
在下列範例中,XML 實例會儲存在 xml 類型的變數中。 value()
方法會從 XML 擷取 ProductID
屬性值, 該值接著會指派給 int 變數。
DECLARE @myDoc XML;
DECLARE @ProdID INT;
SET @myDoc = '<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features>
<Warranty>1 year parts and labor</Warranty>
<Maintenance>3 year parts and labor extended maintenance is available</Maintenance>
</Features>
</ProductDescription>
</Root>';
SET @ProdID = @myDoc.value('(/Root/ProductDescription/@ProductID)[1]', 'int');
SELECT @ProdID;
因此,傳回 的值 1
。
雖然 XML 實例中只有一個 ProductID
屬性,但靜態輸入規則會要求您明確指定路徑表達式會傳回單一屬性。 因此,會將 [1]
新增至路徑表達式的結尾。 如需靜態類型的詳細資訊,請參閱 XQuery 與靜態類型。
B. 使用 value() 方法從 XML 類型資料行擷取整數值
下列查詢是針對 AdventureWorks2022
資料庫中的 xml 類型資料行 (CatalogDescription
) 所指定。 此查詢會從儲存在資料行中的每一個 XML 執行個體擷取 ProductModelID
屬性值。
SELECT CatalogDescription.value(
'declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
(/PD:ProductDescription/@ProductModelID)[1]', 'int') AS Result
FROM Production.ProductModel
WHERE CatalogDescription IS NOT NULL
ORDER BY Result DESC;
上一個查詢的附註:
namespace
關鍵字是用來定義命名空間前置詞。根據靜態類型需求,會在
[1]
方法的路徑運算式結尾加入value()
,以明確指出路徑運算式會傳回單一值。
結果集如下所示。
35
34
28
25
23
19
C. 使用 value() 方法從 XML 類型資料行擷取字串值
下列查詢會針對資料庫中的 xml 類型資料列 (CatalogDescription
) AdventureWorks2022
指定。 此查詢會從儲存在資料行中的每一個 XML 執行個體擷取 ProductModelName
屬性值。
SELECT CatalogDescription.value(
'declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
(/PD:ProductDescription/@ProductModelName)[1]', 'varchar(50)') AS Result
FROM Production.ProductModel
WHERE CatalogDescription IS NOT NULL
ORDER BY Result DESC;
上一個查詢的附註:
namespace
關鍵字是用來定義命名空間前置詞。根據靜態類型需求,會在
[1]
方法的路徑運算式結尾加入value()
,以明確指出路徑運算式會傳回單一值。
結果集如下所示。
Touring-2000
Touring-1000
Road-450
Road-150
Mountain-500
Mountain 100
D. 使用 value() 和 exist() 方法來從 XML 類型數據行擷取值
下列範例顯示如何使用 xml 資料類型的 value()
方法和 exist() 方法。 value()
方法是用於擷取 XML 中的 ProductModelID
屬性值。 exist()
子句中的 WHERE
方法則是用於篩選資料表中的資料列。
此查詢會從將保固資訊 (<Warranty>
元素) 作為功能之一的 XML 執行個體中,擷取產品型號識別碼。 WHERE
子句中的條件會使用 exist()
方法,只擷取滿足此條件的資料列。
SELECT CatalogDescription.value(
'declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
(/PD:ProductDescription/@ProductModelID)[1]', 'int') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist(
'declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
declare namespace wm="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";
/PD:ProductDescription/PD:Features/wm:Warranty') = 1;
上一個查詢的附註:
CatalogDescription
資料行是具類型的 XML 資料行。 這表示它有相關聯的結構描述集合。 在 Modules 和 Prologs - XQuery Prolog 中,命名空間宣告是用來定義稍後在查詢主體中使用的前置詞。exist()
如果方法傳1
回 (true),表示 XML 實例包含<Warranty>
子專案做為其中一項功能。value()
子句中的SELECT
方法就會擷取ProductModelID
屬性值做為整數。
部分結果如下:
19
23
...
E. 使用 exist() 方法,而不是 value() 方法
基於效能的考量,不要在述詞中使用 value()
方法來與關聯式值做比較,而是使用 exist()
搭配 sql:column()
進行比較。 例如:
CREATE TABLE T (c1 INT, c2 VARCHAR(10), c3 XML);
GO
SELECT c1, c2, c3
FROM T
WHERE c3.value('(/root/@a)[1]', 'integer') = c1;
GO
此程式代碼可以重寫,如下所示:
SELECT c1, c2, c3
FROM T
WHERE c3.exist('/root[@a=sql:column("c1")]') = 1;
GO