Share via


value() 方法 (xml 資料類型)

對 XML 執行 XQuery 並傳回 SQL 類型的值。此方法會傳回純量值。

通常您會使用此方法,從儲存在 xml 類型資料行、參數或變數中的 XML 執行個體擷取值。如此一來,您就可以指定 SELECT 查詢來結合或比較 XML 資料與非 XML 資料行的資料。

語法

value (XQuery, SQLType)

引數

  • XQuery
    是 XQuery 運算式,在 XML 執行個體內擷取資料的一個字串常值。XQuery 最多只能傳回一個值。否則,就傳回錯誤。

  • SQLType
    是慣用的 SQL 類型,要傳回的字串常值。此方法的傳回類型符合 SQLType 參數。SQLType 不能是 xml 資料類型、Common Language Runtime (CLR) 使用者自訂類型、image、text、ntext 或是 sql_variant 資料類型。SQLType 可以是 SQL 使用者自訂資料類型。

value() 方法會隱含使用 Transact-SQL CONVERT 運算子,並試著將 XQuery 運算式的結果 (序列化字串表示法),從 XSD 類型轉換成 Transact-SQL 轉換所指定的對應 SQL 類型。如需 CONVERT 之類型轉換規則的詳細資訊,請參閱<CAST 和 CONVERT (Transact-SQL)>。

[!附註]

基於效能的考量,不要在述詞中使用 value() 方法來與關聯式值做比較,而是使用 exist() 搭配 sql:column() 進行比較。如下列範例 D 所示。

範例

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 類型資料行的值

下列查詢是針對 AdventureWorks 資料庫中的 xml 類型資料行 (CatalogDescription) 所指定。此查詢會從儲存在資料行中的每一個 XML 執行個體擷取 ProductModelID 屬性值。

SELECT CatalogDescription.value('           
    declare namespace PD="https://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 關鍵字是用來定義命名空間前置詞。

  • 根據靜態類型需求,會在 value() 方法的路徑運算式結尾加入 [1],以明確指出路徑運算式會傳回單一值。

以下是部份結果:

-----------
35         
34         
...

C. 使用 value() 和 exist() 方法來擷取 xml 類型資料行的值

下列範例顯示如何使用 xml 資料類型的 value() 方法和 exist() 方法。value() 方法是用於擷取 XML 中的 ProductModelID 屬性值。WHERE 子句中的 exist() 方法則是用於篩選資料表中的資料列。

此查詢會從將保固資訊 (<Warranty> 元素) 做為功能之一的 XML 執行個體中,擷取產品型號識別碼。WHERE 子句中的條件會使用 exist() 方法,只擷取滿足此條件的資料列。

SELECT CatalogDescription.value('
     declare namespace PD="https://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="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";

     /PD:ProductDescription/PD:Features/wm:Warranty ') = 1

下列為上一個查詢的注意事項:

  • CatalogDescription 資料行是具類型的 XML 資料行。這表示它有相關聯的結構描述集合。在 XQuery 初構中,命名空間宣告是用來定義稍後要在查詢主體中使用的前置詞。

  • 如果 exist() 方法傳回 1 (True),表示 XML 執行個體包括 <Warranty> 子元素做為功能之一。

  • SELECT 子句中的 value() 方法就會擷取 ProductModelID 屬性值做為整數。

以下是部份結果:

Result     
-----------
19         
23         
...

D. 使用 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[1]/@a', 'integer') = c1
GO

這可由下列方式來撰寫:

SELECT c1, c2, c3 
FROM T
WHERE c3.exist( '/root[@a=sql:column("c1")]') = 1
GO