Поделиться через


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