2017-05-05 3 views
0

질문과 대답이 응용 프로그램 프로세스의 일부로 포함 된 XML 데이터 열이 있습니다. T-SQL/Dynamic SQL을 통해 달성하고자하는 것은 태그가있는 곳이면 어디서든 고유 한 경로 집합을 파생시키는 것입니다. 그래서 아래의 XML 예를 들어, 나는을 대상으로//고유 한 경로 집합을 파생시키기 위해 XML 데이터 열을 순환하는 T-SQL

로그/클라이언트/클라이언트/절/질문/groupone/질문 같은 것을 기대 로그/클라이언트/클라이언트/절/질문/grouptwo/질문을 목표 것

아이디어는 다음을 사용하여 XML을 반복하여 원하는 태그의 값을 유도하는 것입니다. 즉

는 는

[DATA] .value는 ('(//클라이언트/클라이언트/절/질문/groupone/질문/대상 로그'

문제는, 'NVARCHAR (MAX)를') 각 응용 프로그램은 다른있다 일부 즉, 질문과 XML 구조의 세트가 더 많은 질문이있을 수 있습니다, 일부는 다른 그룹이있을 수 있습니다. 태그는 다음의 경로 무엇인가가있는 경우 그러나 내가 원하는 모든입니다. 내가 가장이 달성 할 수있는 방법

?

<log> 
    <clients> 
    <client> 
    <section name ="Apps”> 
    <questions> 
     <groupone> 
     <question> 
     <target>Age</target> 
     </question> 
     <question> 
     <target> Height</target> 
     </question> 
     <question> 
     <target> Weight</target> 
     </question> 
     </groupone> 
     <grouptwo name = "exercise"> 
     <wording>what is your name</wording> 
     <question> 
     <id>1</id> 
     <target>def<target> 
     </question> 
     </grouptwo> 
    </questions> 
    </section> 
    </client> 
    </clients> 
</log> 

답변

3

FROM OPENXML으로 된 구식 접근법이 여기에 옵션 일 수 있습니다. Check this answer.

this link에서 John Cappelletti는 수시로 게시하는 기능을 발견 할 수 있습니다.이 기능을 사용하면 XML (기능 코드 아래의 크레딧)을 조각 낼 수 있습니다.

하지만 실제로 실현하려고하는 것이 확실하지 않습니다 ... 경로가 필요한 이유는 무엇입니까? 모든 대상 노드의 값에 관심이 있다면 당신이 정말로 당신이 확인할 수모든 모든 것을해야하는 경우이

SELECT t.value(N'(text())[1]','nvarchar(max)') 
FROM @xml.nodes('//target') AS A(t); 

(// 깊은 검색은 정확한 XPath이 필요하지 않습니다)처럼 당신이 뭔가를 할 수 있습니다

CREATE FUNCTION [dbo].[udf-XML-Hier](@XML xml) 

Returns Table 
As Return 

with cte0 as ( 
        Select Lvl  = 1 
         ,ID  = Cast(1 as int) 
         ,Pt  = Cast(NULL as int) 
         ,Element = x.value('local-name(.)','varchar(150)') 
         ,Attribute = cast('' as varchar(150)) 
         ,Value  = x.value('text()[1]','varchar(max)') 
         ,XPath  = cast(concat(x.value('local-name(.)','varchar(max)'),'[' ,cast(Row_Number() Over(Order By (Select 1)) as int),']') as varchar(max)) 
         ,Seq  = cast(1000000+Row_Number() over(Order By (Select 1)) as varchar(max)) 
         ,AttData = x.query('.') 
         ,XMLData = x.query('*') 
        From @XML.nodes('/*') a(x) 
        Union All 
        Select Lvl  = p.Lvl + 1 
         ,ID  = Cast((Lvl + 1) * 1024 + (Row_Number() Over(Order By (Select 1)) * 2) as int) * 10 
         ,Pt  = p.ID 
         ,Element = c.value('local-name(.)','varchar(150)') 
         ,Attribute = cast('' as varchar(150)) 
         ,Value  = cast(c.value('text()[1]','varchar(max)') as varchar(max)) 
         ,XPath  = cast(concat(p.XPath,'/',c.value('local-name(.)','varchar(max)'),'[',cast(Row_Number() Over(PARTITION BY c.value('local-name(.)','varchar(max)') Order By (Select 1)) as int),']') as varchar(max)) 
         ,Seq  = cast(concat(p.Seq,' ',10000000+Cast((Lvl + 1) * 1024 + (Row_Number() Over(Order By (Select 1)) * 2) as int) * 10) as varchar(max)) 
         ,AttData = c.query('.') 
         ,XMLData = c.query('*') 
        From cte0 p 
        Cross Apply p.XMLData.nodes('*') b(c) 
      ) 
    , cte1 as ( 
        Select R1 = Row_Number() over (Order By Seq),A.* 
        From (
          Select Lvl,ID,Pt,Element,Attribute,Value,XPath,Seq From cte0 
          Union All 
          Select Lvl  = p.Lvl+1 
           ,ID  = p.ID + Row_Number() over (Order By (Select NULL)) 
           ,Pt  = p.ID 
           ,Element = p.Element 
           ,Attribute = x.value('local-name(.)','varchar(150)') 
           ,Value  = x.value('.','varchar(max)') 
           ,XPath  = p.XPath + '/@' + x.value('local-name(.)','varchar(max)') 
           ,Seq  = cast(concat(p.Seq,' ',10000000+p.ID + Row_Number() over (Order By (Select NULL))) as varchar(max)) 
          From cte0 p 
          Cross Apply AttData.nodes('/*/@*') a(x) 
         ) A 
       ) 

Select A.R1 
     ,R2 = IsNull((Select max(R1) From cte1 Where Seq Like A.Seq+'%'),A.R1) 
     ,A.Lvl 
     ,A.ID 
     ,A.Pt 
     ,A.Element 
     ,A.Attribute 
     ,A.XPath 
     ,Title = Replicate('|---',Lvl-1)+Element+IIF(Attribute='','','@'+Attribute) 
     ,A.Value 
From cte1 A 

/* 
Source: http://beyondrelational.com/modules/2/blogs/28/posts/10495/xquery-lab-58-select-from-xml.aspx 

Taken from John Cappelletti: https://stackoverflow.com/a/42729851/5089204 

Declare @XML xml='<person><firstname preferred="Annie" nickname="BeBe">Annabelle</firstname><lastname>Smith</lastname></person>' 
Select * from [dbo].[udf-XML-Hier](@XML) Order by R1 
*/ 
GO 

DECLARE @xml XML= 
'<log> 
    <clients> 
    <client> 
    <section name ="Apps"> 
    <questions> 
     <groupone> 
     <question> 
     <target>Age</target> 
     </question> 
     <question> 
     <target> Height</target> 
     </question> 
     <question> 
     <target> Weight</target> 
     </question> 
     </groupone> 
     <grouptwo name = "exercise"> 
     <wording>what is your name</wording> 
     <question> 
     <id>1</id> 
     <target>def</target> 
     </question> 
     </grouptwo> 
    </questions> 
    </section> 
    </client> 
    </clients> 
</log>'; 

SELECT * FROM dbo.[udf-XML-Hier](@xml); 
GO 
+0

감사합니다. 내 문제가 해결되었습니다. 매우 역동적 인 접근 방식 – Sharingan