Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

sql query xml valori che restituiscono NULL

Il tuo xml include uno spazio dei nomi xmlns="http://www.webserviceX.NET/" , che è lo spazio dei nomi predefinito . Devi dichiararlo o utilizzare un carattere jolly per il prefisso.

Con XML ci sono alcune buone pratiche:

  • Sii il più specifico possibile
  • Solo navigazione in avanti
  • Importante Se la creazione dell'XML è sotto il tuo controllo, cambia il formato della data e dell'ora in ISO8601. I tuoi formati sono specifici della cultura e possono facilmente portare a errori di conversione su sistemi diversi. Il migliore era un valore combinato come <DateAndTime>2017-05-23T12:37:00</DateAndTime>

Per il tuo problema ci sono diversi approcci:

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>';

--Miglior approccio:XMLNAMESPACES per dichiarare lo spazio dei nomi predefinito

WITH XMLNAMESPACES(DEFAULT 'http://www.webserviceX.NET/')
SELECT @xml.value(N'(/string/StockQuotes/Stock/Symbol/text())[1]',N'nvarchar(max)');

--Dichiarazione implicita dello spazio dei nomi:

SELECT @xml.value(N'declare namespace ns="http://www.webserviceX.NET/";
                   (/ns:string/ns:StockQuotes/ns:Stock/ns:Symbol/text())[1]',N'nvarchar(max)');

--Non consigliato nella maggior parte dei casi, ma buono per persone pigre MrGreen

SELECT @xml.value(N'(//*:Symbol)[1]',N'nvarchar(max)');

--Se vuoi leggere più valori dello stesso livello, puoi usare .nodes per impostare il nodo corrente su ...<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);