Método de valor() (Tipo de dados xml)

Executa uma XQuery em relação ao XML e retorna um valor de tipo SQL. Este método retorna um valor escalar.

Este método é usado, em geral, para extrair um valor de uma instância de XML armazenada em uma coluna de tipo, um parâmetro ou uma variável xml. Dessa forma, você pode especificar consultas SELECT que combinam ou comparam dados de XML com dados em colunas não XML.

Sintaxe

value (XQuery, SQLType)

Argumentos

  • XQuery
    É a expressão XQuery, uma literal de cadeia de caracteres, que recupera dados dentro da instância de XML. A XQuery deve retornar no máximo um valor. Caso contrário, um erro é retornado.

  • SQLType
    É o tipo SQL preferido, uma literal de cadeia de caracteres, a ser retornado. O tipo de retorno desse método corresponde ao parâmetro SQLType. SQLType não pode ser um tipo de dados xml, um tipo de common language runtime (CLR) definido pelo usuário, image, text, ntext, ou tipo de dados sql_variant. SQLType pode ser um tipo de dados SQL definido pelo usuário.

O método value() usa o operador Transact-SQL CONVERT implicitamente e tenta converter o resultado da expressão XQuery, a representação serializada de cadeia de caracteres, do tipo XSD para o tipo SQL correspondente especificado pela conversão Transact-SQL. Para obter mais informações sobre as regras de aplicação de tipo para CONVERT, consulte CAST e CONVERT (Transact-SQL).

ObservaçãoObservação

Por motivos de desempenho, em vez de usar o método value() em um predicado para comparar com um valor relacional, use exist() com sql:column(). Isso é demonstrado no exemplo D a seguir.

Exemplos

A. Usando o método de valor() em relação a uma variável de tipo xml

No exemplo a seguir, uma instância XML é armazenada em uma variável de tipo xml. O método value() recupera o valor de atributo ProductID do XML. O valor é então atribuído a uma variável 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

O valor 1 é retornado como resultado.

Embora exista apenas um atributo ProductID na instância XML, as regras de digitação estática exigem que você especifique explicitamente que a expressão de caminho retorne um singleton. Portanto, o [1] adicional é especificado ao término da expressão de caminho. Para obter mais informações sobre digitação estática, consulte XQuery e digitação estática.

B. Usando o método de valor () para recuperar um valor de uma de tipo xml

A consulta a seguir é especificada em relação a uma coluna de tipo xml (CatalogDescription) no banco de dados AdventureWorks2008R2. A consulta recupera valores de atributo ProductModelID de cada instância de XML armazenada na coluna.

SELECT CatalogDescription.value('           
    declare namespace PD="https://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           

Observe o seguinte na consulta anterior:

  • A palavra-chave namespace é usada para definir um prefixo de namespace.

  • De acordo com as exigências de digitação estática, [1] é adicionado no final da expressão de caminho no método value() a fim de indicar explicitamente que a expressão de caminho retorna um singleton.

Este é o resultado parcial:

-----------
35         
34         
...

C. Usando os métodos valor() e exist() para recuperar valores de uma coluna tipo xml

O exemplo a seguir demonstra o uso do método value() e do método exist() do tipo de dados xml. O método value() é usado para recuperar valores de atributo ProductModelID do XML. O método exist() na cláusulaWHERE é usado para filtrar as linhas da tabela.

A consulta recupera IDs de modelo de produto de instâncias XML que incluem informações de garantia (o elemento <Warranty>) como um dos recursos. A condição na cláusula WHERE usa o método exist() para recuperar apenas as linhas que satisfazem esta condição.

SELECT CatalogDescription.value('
     declare namespace PD="https://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="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";

     /PD:ProductDescription/PD:Features/wm:Warranty ') = 1

Observe o seguinte na consulta anterior:

  • A coluna CatalogDescription é uma coluna XML com tipo. Isso significa que ela possui uma coleção de esquema associada ao mesmo. Em XQuery Prolog, a declaração de namespace é usada para definir o prefixo que é usado posteriormente no corpo da consulta.

  • Se o método exist() retorna um 1 (True), isso indica que a instância XML inclui o elemento filho <Warranty> como um dos recursos.

  • O método value() na cláusula SELECT recupera os valores de atributo ProductModelID como inteiros.

Este é o resultado parcial:

Result     
-----------
19         
23         
...

D. Usando o método exist() em vez do método value()

Por motivos de desempenho, em vez de usar o método value() em um predicado para comparar com um valor relacional, use exist() com sql:column(). Por exemplo:

CREATE TABLE T (c1 int, c2 varchar(10), c3 xml)
GO

SELECT c1, c2, c3 
FROM T
WHERE c3.value( '/root[1]/@a', 'integer') = c1
GO

Isso pode ser gravado da seguinte maneira:

SELECT c1, c2, c3 
FROM T
WHERE c3.exist( '/root[@a=sql:column("c1")]') = 1
GO