<ActiveDig>
<Dig IsPrim="True">
<Code>3342</Code>
<Name>abc</Name>
</Dig>
<Dig IsPrim="False">
<Code>5342</Code>
<Name>xyz</Name>
</Dig>
</ActiveDig>
我正在尝试将其加载到表中,如下所示:
| Dig_Isprim | Code | Name |
|-------------|--------|--------|
| True | 3342 | abc |
|-------------|--------|--------|
| False | 5342 | xyz |
答案 0 :(得分:0)
示例强>
Set @XML ='
<ActiveDig>
<Dig IsPrim="True">
<Code>3342</Code>
<Name>abc</Name>
</Dig>
<Dig IsPrim="False">
<Code>5342</Code>
<Name>xyz</Name>
</Dig>
</ActiveDig>
'
Select Dig_Isprim = lvl1.n.value('@IsPrim','varchar(50)')
,Code = lvl1.n.value('./Code[1]','varchar(50)')
,Name = lvl1.n.value('./Name[1]','varchar(50)')
From @XML.nodes('ActiveDig/*') lvl1(n)
<强>返回强>
Dig_Isprim Code Name
True 3342 abc
False 5342 xyz
EDIT -FULLY DYNAMIC SQL
以下使用表值函数将几乎任何XML解析为数据集。然后我们在一些Dynamic XML中有一些Dynamic XML。
看起来有点复杂,但是当你看到各个部分时,情况就不那么糟了。
示例强>
Declare @XML xml ='
<ActiveDig>
<Dig IsPrim="True">
<Code>3342</Code>
<Name>abc</Name>
</Dig>
<Dig IsPrim="False">
<Code>5342</Code>
<Name>xyz</Name>
</Dig>
</ActiveDig>
'
Declare @SQL varchar(max) = '
Select * Into #Temp
From (
Select *
,Item = concat(Element,IIF(Attribute='''','''',''_''),Attribute )
,RowN = sum(case when Lvl=2 then 1 else 0 end) over (Order by R1)
From [dbo].[tvf-XML-Hier](cast('''+cast(@XML as varchar(max))+''' as xml))
) A
Where Value is not null
Declare @SQL varchar(max) = ''
Select *
From ( Select RowN,Item,Value From #Temp ) A
Pivot (max([Value]) For [Item] in ('' + Stuff((Select Top 1000 '',''+QuoteName(Item) From (Select Distinct Item,Seq=min(R1) over (Partition By Item) from #Temp ) A Order By Seq For XML Path('''')),1,1,'''') + '') ) p''
Exec(@SQL);
'
Exec(@SQL)
<强>返回强>
您可能会注意到唯一指定的是Lvl 2 ...没有属性名称或节点名称。
感兴趣的UDF
CREATE FUNCTION [dbo].[tvf-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
Declare @XML xml='<person><firstname preferred="Annie" nickname="BeBe">Annabelle</firstname><lastname>Smith</lastname></person>'
Select * from [dbo].[tvf-XML-Hier](@XML) Order by R1
*/
编辑2-只是为了帮助实现可视化
如果您只是运行以下内容:
Select * From [dbo].[tvf-XML-Hier](@XML) Order By R1
结果将