Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

requête sql valeurs xml retournant NULL

Votre xml inclut un espace de noms xmlns="http://www.webserviceX.NET/" , qui est l'espace de noms par défaut . Vous devez soit le déclarer, soit utiliser un caractère générique pour le préfixe.

Avec XML, il existe quelques bonnes pratiques :

  • Soyez aussi précis que possible
  • Navigation vers l'avant uniquement
  • Important Si la création du XML est sous votre contrôle, changez le format de date et d'heure en ISO8601. Vos formats sont spécifiques à une culture et peuvent facilement entraîner des erreurs de conversion sur différents systèmes. Le meilleur était une valeur combinée telle que <DateAndTime>2017-05-23T12:37:00</DateAndTime>

Pour votre problème, il existe plusieurs approches :

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

--Meilleure approche :XMLNAMESPACES pour déclarer l'espace de noms par défaut

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

--Déclaration d'espace de noms implicite :

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 recommandé dans la plupart des cas, mais bon pour les gens paresseux :-D

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

--Si vous voulez lire plus de valeurs du même niveau, vous pouvez utiliser .nodes pour définir le nœud actuel sur ...<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);