Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

XML-Werte der SQL-Abfrage, die NULL zurückgeben

Ihr XML enthält einen Namespace xmlns="http://www.webserviceX.NET/" , das ist der Standard-Namespace . Sie müssen es entweder deklarieren oder einen Platzhalter für das Präfix verwenden.

Bei XML gibt es einige Best Practices:

  • Sei so spezifisch wie möglich
  • Nur Vorwärtsnavigation
  • Wichtig Wenn die Erstellung des XML unter Ihrer Kontrolle liegt, ändern Sie das Datums- und Zeitformat in ISO8601. Ihre Formate sind kulturspezifisch und können leicht zu Konvertierungsfehlern auf verschiedenen Systemen führen. Am besten war ein kombinierter Wert wie <DateAndTime>2017-05-23T12:37:00</DateAndTime>

Für Ihr Problem gibt es mehrere Ansätze:

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

--Bester Ansatz:XMLNAMESPACES um den Standard-Namespace zu deklarieren

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

--Implizite Namespace-Deklaration:

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

--In den meisten Fällen nicht empfohlen, aber gut für faule Leute :-D

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

--Wenn Sie mehr Werte der gleichen Ebene lesen möchten, können Sie .nodes verwenden um den aktuellen Knoten auf ...<Stock> zu setzen .

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