Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

valores xml de consulta sql retornando NULL


Seu xml inclui um namespace xmlns="http://www.webserviceX.NET/" , que é o namespace padrão . Você deve declará-lo ou usar um curinga para o prefixo.

Com XML, existem algumas práticas recomendadas:
  • Seja o mais específico possível
  • Somente navegação para frente
  • Importante Se a criação do XML estiver sob seu controle, altere o formato de data e hora para ISO8601. Seus formatos são específicos da cultura e podem facilmente levar a erros de conversão em diferentes sistemas. Melhor foi um valor combinado como <DateAndTime>2017-05-23T12:37:00</DateAndTime>

Para o seu problema, existem várias abordagens:
DECLARE @xml XML=
N'<string xmlns="http://www.webserviceX.NET/">
  <StockQuotes>
    <Stock>
      <Symbol>ENGI.PA</Symbol>
      <Last>13.53</Last>
      <Date>5/23/2017</Date>
      <Time>12:37pm</Time>
      <!--more elements -->
    </Stock>
  </StockQuotes>
</string>';

--Melhor abordagem:XMLNAMESPACES para declarar o espaço de nomes padrão
WITH XMLNAMESPACES(DEFAULT 'http://www.webserviceX.NET/')
SELECT @xml.value(N'(/string/StockQuotes/Stock/Symbol/text())[1]',N'nvarchar(max)');

--Declaração de namespace implícita:
SELECT @xml.value(N'declare namespace ns="http://www.webserviceX.NET/";
                   (/ns:string/ns:StockQuotes/ns:Stock/ns:Symbol/text())[1]',N'nvarchar(max)');

--Não recomendado na maioria dos casos, mas bom para preguiçosos :-D
SELECT @xml.value(N'(//*:Symbol)[1]',N'nvarchar(max)');

--Se você quiser ler mais valores do mesmo nível, você pode usar .nodes para definir o nó atual para ...<Stock> .
WITH XMLNAMESPACES(DEFAULT 'http://www.webserviceX.NET/')
SELECT st.value('(Symbol/text())[1]',N'nvarchar(max)')
      ,st.value('(Last/text())[1]',N'decimal(10,4)')
      --more nodes 
FROM @xml.nodes(N'/string/StockQuotes/Stock') AS A(st);