2017-05-24 1 views
1

반환 나는 xml 구조 경험 나는 아래 xml 구조에서 값을 검색 할 수있는 방법에 대한 시작점을 필요로하고 있지 않다. SQL 쿼리 XML 값은 NULL

는 I는 stored-procedure를 사용 webservice에서 xml 페치 및 테이블 "StockInfoXML의" xml 유형의 xml XML_URL 인 채 테이블 필드에 저장한다.

<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> 
     <Change>+0.06</Change> 
     <Open>13.45</Open> 
     <High>13.59</High> 
     <Low>13.40</Low> 
     <Volume>1524437</Volume> 
     <MktCap>32.95B</MktCap> 
     <PreviousClose>13.47</PreviousClose> 
     <PercentageChange>+0.48%</PercentageChange> 
     <AnnRange>10.77 - 15.20</AnnRange> 
     <Earns>-0.23</Earns> 
     <P-E>N/A</P-E> 
     <Name>ENGIE</Name> 
    </Stock> 
    </StockQuotes> 
</string> 

나는 몇 가지를 시도했지만 null 또는 아무것도를 반환 유지했습니다.

declare @X XML; 

SELECT 
@X = XML_Url 
FROM dbo.StockExchangeInfoXML 

SELECT 
x.s.value('(StockQuotes/Stock/Symbol)[1]', 'nvarchar(50)') AS [Symbol] 
FROM @X.nodes('./StockQuotes/Stock') AS x(s); 

나를 시작할 수있는 사람은 누구입니까? 감사합니다. .

답변

2

으로 XML이 기본 네임 스페이스있는 공간 xmlns="http://www.webserviceX.NET/"을 포함을 XML의 네임 스페이스를 설정해야합니다. 이를 선언하거나 접두사에 와일드 카드를 사용해야합니다.

은 XML로 몇 가지 모범 사례가 : 가능한 한 구체적으로

  • 만 앞으로 탐색
  • 중요는 XML의 생성 날짜와 시간을 변경하려면 제어하에있는 경우 ISO8601 형식. 귀하의 형식은 특정 문화권이므로 다른 시스템에서 쉽게 전환 오류가 발생할 수 있습니다.

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

    가 --Best 방법 : XMLNAMESPACES기본 네임 스페이스

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

    를 선언 - 최저 몇 가지 방법이 있습니다 문제에 대한 <DateAndTime>2017-05-23T12:37:00</DateAndTime>

같은 결합 된 값을했다 암시 적 네임 스페이스 선언 :

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

는 알리바이 게으른 사람 - D

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

같은 수준의 이상의 값을 읽을 수 굳이 이렇게, 당신은을 설정 .nodes을 사용할 수 있습니다에 대한 대부분의 경우 권장하지만, 좋은 현재 노드는 ...<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); 
+0

Thx Shnugo가 신속하게 솔루션을 제공합니다! 이것은 나를 위해 그것을했다 :) – FGR

+0

네, 여기에 초보자 그래서 나는 당신의 코멘트를 기대했다! 받아들이는 방법을 찾기 위해 조금 고생했지만, 내가 관리했다고 생각합니다. 다시 Thx. – FGR

1

당신이 얻을 값 전에

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> 
     <Change>+0.06</Change> 
     <Open>13.45</Open> 
     <High>13.59</High> 
     <Low>13.40</Low> 
     <Volume>1524437</Volume> 
     <MktCap>32.95B</MktCap> 
     <PreviousClose>13.47</PreviousClose> 
     <PercentageChange>+0.48%</PercentageChange> 
     <AnnRange>10.77 - 15.20</AnnRange> 
     <Earns>-0.23</Earns> 
     <P-E>N/A</P-E> 
     <Name>ENGIE</Name> 
    </Stock> 
    </StockQuotes> 
</string>' 

;WITH XMLNAMESPACES('http://www.webserviceX.NET/' as ns) 
SELECT 
x.s.value('(./ns:Symbol)[1]', 'varchar(50)') AS [Symbol] 
FROM @xml.nodes('/ns:string/ns:StockQuotes/ns:Stock') AS x(s); 

반환

Symbol 
-------- 
ENGI.PA 
+0

이 정답 (내 옆에서 +1)이지만, 조금 개선 될 수있다 :'의 xmlns가 = "뭔가"'* 표시의 기본 네임 스페이스 *을 정의로, 모든 네임 스페이스 접두사에 대한 필요가 없습니다 ... 더 이상 나는'을 추천하지 않을 것이다.nodes()'하나의 단일 값을 읽는 것 ... 약간의 오버 헤드 ... – Shnugo

+0

@Shnugo와 훌륭한 대답에 감사드립니다. – TriV