共用方式為


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

適用於:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceMicrosoft Fabric 中的 SQL 資料庫

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

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

語法

value ( XQuery , SQLType )

引數

XQuery

XQuery 表達式是字串常值,可擷取 XML 實例內的數據。 XQuery 最多只能傳回一個值。 否則,就會傳回錯誤。

SQLType

要傳回的慣用 SQL 類型,字串常值。 此方法的傳回類型符合 SQLType 參數。 SQLType 可以是使用者定義的 SQL 資料類型。

注意

SQLType 不能是下列其中一種數據類型:xml、imagetext、ntextsql_variant或 Common Language Runtime (CLR) 使用者定義型別。

方法會 value() 隱含使用 Transact-SQL CONVERT 運算符。 value() 會嘗試將 XQuery 運算式的結果、串行化的字串表示,從 XML 架構定義 (XSD) 類型轉換為 Transact-SQL 轉換所指定的對應 SQL 類型。 如需 類型轉換規則 CONVERT的詳細資訊,請參閱 CAST 和 CONVERT

基於效能考慮,您可以搭配 使用 exist()sql:column() 而不是 value() 在述詞中使用 方法,以與關係型值進行比較。 本文稍後會顯示此 exist() 範例。

範例

本文中的程式代碼範例會使用 AdventureWorks2025AdventureWorksDW2025 範例資料庫,您可以從 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 類型資料行擷取整數值

下列查詢是針對 資料庫中的 CatalogDescription 類型資料行 (AdventureWorks2025) 所指定。 此查詢會從儲存在資料行中的每一個 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 類型資料列 (CatalogDescriptionAdventureWorks2025 指定。 此查詢會從儲存在資料行中的每一個 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 類型數據行擷取值

下列範例顯示如何使用 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