sql:column() (XQuery)
Как описано в разделе Привязка реляционных данных внутри XML, при использовании методов XML-данных можно использовать функцию sql:column(), чтобы получить доступ к реляционному значению внутри XQuery.
Например, запрос к экземпляру XML, который хранится в переменной или столбце типа xml, задается с помощью метода query() (тип XML-данных). Кроме того, иногда для совмещения реляционных данных с XML-данными бывает необходимо, чтобы запрос обрабатывал значения еще одного столбца, отличного от XML. Для этого используется функция sql:column().
Значение SQL будет сопоставлено с соответствующим значением XQuery, а в качестве типа этого значения будет присвоен базовый тип XQuery, эквивалентный соответствующему типу SQL.
Синтаксис
sql:column("columnName")
Замечания
Обратите внимание, что ссылка на столбец, указанная в функции sql:column() внутри XQuery, ссылается на столбец в строке, которая обрабатывается в настоящий момент.
В SQL Server ссылаться на экземпляр xml можно только в контексте исходного выражения инструкции вставки XML DML; в противном случае нельзя ссылаться на столбцы, имеющие тип xml или определяемый пользователем тип данных CLR.
Функция sql:column() не поддерживается в операциях JOIN. Вместо этого можно использовать операцию APPLY.
Примеры
А. Получение реляционного значения внутри XML с помощью функции sql:column()
В следующем примере конструирования XML показано получение значений реляционного столбца, отличного от XML, для связывания реляционных данных с XML-данными.
Запрос формирует XML следующей структуры:
<Product ProductID="771" ProductName="Mountain-100 Silver, 38" ProductPrice="3399.99" ProductModelID="19"
ProductModelName="Mountain 100" />
Обратите внимание на следующие особенности созданного кода XML.
Значения атрибутов ProductID, ProductName и ProductPrice извлекаются из таблицы Product.
Значение атрибута ProductModelID получается из таблицы ProductModel.
Чтобы запрос был более интересным, значение атрибута ProductModelName извлекается из столбца CatalogDescription типа xml. Поскольку данные каталога модели продукта XML хранятся не для всех моделей продуктов, с помощью инструкции if получаются только существующие значения.
SELECT P.ProductID, CatalogDescription.query(' declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"; <Product ProductID= "{ sql:column("P.ProductID") }" ProductName= "{ sql:column("P.Name") }" ProductPrice= "{ sql:column("P.ListPrice") }" ProductModelID= "{ sql:column("PM.ProductModelID") }" > { if (not(empty(/pd:ProductDescription))) then attribute ProductModelName { /pd:ProductDescription[1]/@ProductModelName } else () } </Product> ') as Result FROM Production.ProductModel PM, Production.Product P WHERE PM.ProductModelID = P.ProductModelID AND CatalogDescription is not NULL ORDER By PM.ProductModelID
Обратите внимание на следующие особенности предыдущего запроса.
Поскольку значения получаются из двух разных таблиц, предложение FROM задает пару таблиц. Условие в предложении WHERE фильтрует результаты и получает только те продукты, у которых в каталоге есть описание моделей.
Ключевое слово namespace в XQuery Prolog задает префикс пространства имен XML, «pd», который используется в теле запроса. Обратите внимание, что эти псевдонимы таблиц, «P» и «PM», задаются в предложении FROM самого запроса.
С помощью функции sql:column() в XML вносятся значения другого типа.
Фрагмент результата:
ProductID Result
-----------------------------------------------------------------
771 <Product ProductID="771" ProductName="Mountain-100 Silver, 38"
ProductPrice="3399.99" ProductModelID="19"
ProductModelName="Mountain 100" />
...
Следующий запрос создает XML, содержащий сведения о продукте. К этим сведениям относится ProductID, ProductName, ProductPrice и (если значение доступно) ProductModelName для всех продуктов, относящихся к конкретной модели, ProductModelID=19. Затем XML присваивается переменной @x типа xml.
declare @x xml
SELECT @x = CatalogDescription.query('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
<Product
ProductID= "{ sql:column("P.ProductID") }"
ProductName= "{ sql:column("P.Name") }"
ProductPrice= "{ sql:column("P.ListPrice") }"
ProductModelID= "{ sql:column("PM.ProductModelID") }" >
{ if (not(empty(/pd:ProductDescription))) then
attribute ProductModelName { /pd:ProductDescription[1]/@ProductModelName }
else
()
}
</Product>
')
FROM Production.ProductModel PM, Production.Product P
WHERE PM.ProductModelID = P.ProductModelID
And P.ProductModelID = 19
select @x
См. также