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

適用於:SQL ServerAzure SQL DatabaseAzure SQL 受控執行個體

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

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

Syntax

value (XQuery, SQLType)  

注意

若要檢視 SQL Server 2014 (12.x) 和舊版的 Transact-SQL 語法,請參閱 舊版檔

引數

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

SQLType
是慣用的 SQL 類型,要傳回的字串常值。 此方法的傳回類型符合 SQLType 參數。 SQLType 不可為 xml 資料類型、通用語言執行平台 (CLR) 使用者定義型別、imagetextntextsql_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="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           
...  

C. 使用 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 資料行。 這表示它有相關聯的結構描述集合。 在 XQuery 初構中,命名空間宣告是用來定義稍後要在查詢主體中使用的前置詞。

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

  • value() 子句中的 SELECT 方法就會擷取 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[@a=sql:column("c1")]/@a)[1]', 'integer') = c1  
GO  

這可由下列方式來撰寫:

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

另請參閱

使用 WITH XMLNAMESPACES 將命名空間加入至查詢
比較具類型的 XML 與不具類型的 XML
建立 XML 資料的執行個體
xml 資料類型方法
XML 資料修改語言 (XML DML)