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 或公共语言运行时(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 示例和社区项目主页下载它。
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()
以显式指示路径表达式返回 1。
结果集如下。
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()
以显式指示路径表达式返回 1。
结果集如下。
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 实例中检索产品型号 ID。 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