Função sql:column() (XQuery)

Como descrito no tópico, Associando dados relacionais dentro do XML, você pode usar a função sql:column(() ao utilizar Métodos de tipo de dados XML para expor um valor relacional dentro do XQuery.

Por exemplo, o método query() (tipo de dados XML) é usado para especificar uma consulta em uma instância XML que esteja armazenada em uma variável ou coluna do tipo xml. Às vezes, você também pode desejar que sua consulta use valores de outra coluna que não seja XML, para agrupar dados relacionais e XML. Para fazer isso, use a função sql:column().

O valor SQL será mapeado para um valor correspondente XQuery e seu tipo será um tipo base XQuery equivalente ao tipo de SQL correspondente.

Sintaxe

sql:column("columnName")

Comentários

Observe que essa referência a uma coluna especificada na função sql:column() dentro de um XQuery refere-se a uma coluna na linha que está sendo processada.

No SQL Server, você só pode se referir a uma instância xml no contexto de uma expressão de origem de uma instrução XML-DML insert; caso contrário, não será possível fazer referência a colunas do tipo xml ou tipo de dado CLR definido pelo usuário.

Não é oferecido suporte à função sql:column() nas operações JOIN. Em vez disso, pode ser usada a operação APPLY.

Exemplos

A. Uso de sql:column() para recuperar o valor relacional no XML

Na construção de XML, o exemplo a seguir ilustra como você pode recuperar valores de uma coluna relacional não XML para associar dados relacionais e XML.

A consulta constrói XML que tenha a seguinte forma:

<Product ProductID="771" ProductName="Mountain-100 Silver, 38" ProductPrice="3399.99" ProductModelID="19" 
  ProductModelName="Mountain 100" />

Observe o seguinte no XML construído:

  • São obtidos os valores de atributo ProductID, ProductName e ProductPrice na tabela Product.

  • O valor de atributo ProductModelID é recuperado na tabela ProductModel.

  • Para tornar a consulta mais interessante, o valor de atributo ProductModelName é obtido na coluna CatalogDescription do tipo xml. Como as informações do catálogo de modelo do produto XML não são armazenadas para todos os modelos de produtos, a instrução if será usada para recuperar o valor somente se ele existir.

    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
    

Observe o seguinte na consulta anterior:

  • Como os valores são recuperados em duas tabelas diferentes, a cláusula FROM especifica duas tabelas. A condição na cláusula WHERE filtra o resultado e recupera apenas produtos cujos modelos de produto tenham descrições de catálogo.

  • A palavra-chave namespace no Prólogo do XQuery define um prefixo de namespace XML, "pd", usado no corpo da consulta. Observe que os aliases de tabela, "P" e "PM", são definidos na cláusula FROM da própria consulta.

  • A função sql:column() é usada para reunir valores não XML no XML.

Este é o resultado parcial:

ProductID               Result
-----------------------------------------------------------------
771         <Product ProductID="771"                   ProductName="Mountain-100 Silver, 38" 
                  ProductPrice="3399.99" ProductModelID="19" 
                  ProductModelName="Mountain 100" />
...

A consulta a seguir constrói XML que contenha informações específicas do produto. Tais informações incluem ProductID, ProductName, ProductPrice e, se disponível, ProductModelName de todos os produtos que pertencem a um modelo de produto específico, ProductModelID=19. O XML é então atribuído à variável @x do tipo 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