Método Value() (Tipo de dados XML)

Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada de SQL do Azure

Executa um XQuery em XML e retorna um valor do 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 SELECT consultas que combinam ou comparam dados XML com dados em colunas não XML.

Sintaxe

value ( XQuery , SQLType )

Observação

Para exibir a sintaxe do Transact-SQL para o SQL Server 2014 (12.x) e versões anteriores, confira a Documentação das versões anteriores.

Argumentos

XQuery

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

SQLType

O tipo SQL preferencial, um 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 definido pelo usuário CLR (Common Language Runtime), imagem, texto, ntext ou sql_variant tipo de dados. SQLType pode ser um tipo de dados SQL definido pelo usuário.

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

Por motivos de desempenho, você pode usar exist() com sql:column() em vez de usar o value() método em um predicado, para comparar com um valor relacional. Este exist() exemplo é mostrado posteriormente neste artigo.

Exemplos

Este artigo requer o banco de dados de exemplo AdventureWorks2022, que pode ser baixado na home page Microsoft SQL Server Samples and Community Projects.

R. Use o método value() em uma variável de tipo XML

No exemplo a seguir, uma instância XML é armazenada em uma variável do 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;

Um valor de 1 é retornado como resultado.

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

B. Use o método value() para recuperar um valor de uma coluna de tipo XML

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

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;

Observação da 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.

Eis o resultado parcial:

35
34
...

C. Use os métodos value() e exist() para recuperar valores de uma coluna de 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="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;

Observação da consulta anterior:

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

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

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

Eis o resultado parcial:

19
23
...

D. Use 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/@a)[1]', 'integer') = c1;
GO

Esse código pode ser reescrito da seguinte maneira:

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