sql >> データベース >  >> RDS >> Sqlserver

T-SQLがXMLデータ列をループして、一意のパスのセットを導出します

    FROM OPENXMLを使用した古いアプローチ ここでのオプションかもしれません。 この回答を確認してください

    このリンク John Cappellettiが時々投稿する関数があり、XML(関数のコードの下のクレジット)を細断処理します。

    しかし、私にはわかりません、あなたが本当に達成しようとしていること...なぜあなたは道が必要なのですか?すべてのターゲットノードの値に関心がある場合は、次のようにすることができます(//を使用した詳細検索 正確なXPathは必要ありません )

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

    本当にすべてが必要な場合 これを確認できます:

    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
    



    1. AndroidSQLiteのテーブルの削除は実際には行を削除しません

    2. SQLServer-更新時の内部結合

    3. 別のテーブルの列によるPHP/MySQLの順序

    4. MicrosoftT-SQLからOracleSQLへの変換