Метод value() (тип данных XML)
Область применения: SQL Server
База данных SQL Azure Управляемый экземпляр SQL Azure
Выполняет XQuery для XML и возвращает значение типа 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, сериализованное строковое представление из типа XSD xml Schema Definition (XSD) в соответствующий тип SQL, заданный преобразованием Transact-SQL. Дополнительные сведения о правилах CONVERT
приведения типов см. в разделе CAST и CONVERT.
По соображениям производительности можно использовать exist()
sql:column()
вместо использования value()
метода в предикате, чтобы сравнить с реляционным значением. Этот exist()
пример показан далее в этой статье.
Примеры
Примеры кода Transact-SQL в этой статье используют AdventureWorks2022
базу данных или AdventureWorksDW2022
пример базы данных, которую можно скачать с домашней страницы примеров и проектов сообщества Microsoft SQL Server.
А. Использование метода value() для переменной типа XML
В следующем примере экземпляр 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.
В следующем примере выполняется запрос к столбцу типа xml (CatalogDescription
) в базе данных AdventureWorks2022
. Запрос извлекает значения атрибутов ProductModelID
из каждого экземпляра XML, который хранится в столбце.
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
В. Используйте метод value() для получения строкового значения из столбца типа XML
Следующий запрос указан для столбца типа XML (CatalogDescription
) в AdventureWorks2022
базе данных. Запрос извлекает значения атрибутов ProductModelName
из каждого экземпляра XML, который хранится в столбце.
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(), возвращающих тип данных xml. Метод value()
извлекает значения атрибутов ProductModelID
из экземпляров XML. Метод exist()
в предложении WHERE
фильтрует строки, извлеченные из таблицы.
Запрос извлекает идентификаторы моделей продуктов из экземпляров XML, которые среди прочего содержат сведения о гарантии (элемент <Warranty>
). Условие в предложении 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-столбцом. Это означает, что с ним связан набор схем. В модулях и prologs — XQuery Prolog объявление пространства имен используется для определения префикса, который используется позже в тексте запроса.exist()
Если метод возвращает1
(true), он указывает, что экземпляр XML включает<Warranty>
дочерний элемент в качестве одной из функций.Метод
value()
в предложенииSELECT
затем извлекает значения атрибутовProductModelID
в виде целых чисел.
Ниже приведен частичный результат:
19
23
...
Е. Используйте метод 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