我有以下xml doc
<Root>
<Translation>
<Entry language ="ES" text = "Alsace"/>
<Entry language ="DE" text = "Elsass"/>
<Entry language ="EN" text = "Alsace"/>
</Translation>
<Translation>
<Entry language ="ES" text = "Brittany"/>
<Entry language ="DE" text = "Bretagne"/>
<Entry language ="EN" text = "Brittany"/>
</Translation>
</Root>
我需要将它切碎成一张桌子,同时保留这些团体。 因此,因为translation元素缺少任何id属性,所以分组隐含在结构中。
表格结果应如下所示。
translation_id, lanuage, text
---------------------------------
1,ES, Alsace
1,DE, Elsass
1,EN, Alsace
2,ES , Brittany
2,DE, Bretagne
2,EN Brittany
我尝试了各种各样的事情,比如
select newid(),
( select rows.n.value('(@language)[1]', 'nvarchar(max)')
from @p.nodes('/Translation/Entry') rows(n)
)
from @p.nodes('/Translation') rows(n)
但似乎无法使用某种循环来获取分组ID。
由于
答案 0 :(得分:2)
没有循环? OK ......
select
rn,
t2.Entry.value('./@language','varchar(5)') ,
t2.Entry.value('./@text','varchar(50)')
from
(
select
row_number() over (order by rows.n) as rn,
rows.n.query('.') as trans
from @p.nodes('/Root/Translation') rows(n)
) trans
cross apply trans.nodes('Translation/Entry') as t2(Entry)
答案 1 :(得分:0)
最终解决了这个问题。不漂亮,我认为必须有一种方法可以在没有循环的情况下完成它。
declare @p xml
set @p =
'<Translation>
<Entry language ="ES" text = "Alsace"/>
<Entry language ="DE" text = "Elsass"/>
<Entry language ="EN" text = "Alsace"/>
</Translation>
<Translation>
<Entry language ="ES" text = "Aquitaine"/>
<Entry language ="DE" text = "Aquitanien"/>
<Entry language ="EN" text = "Aquitaine"/>
</Translation>
'
declare @trans table (id int identity, t xml, [guid] varchar(255))
declare @result table ([guid] varchar(255), language char(2), [text] nvarchar(max) )
declare @no int , @i int, @guid varchar(255), @t xml
insert @trans
(t, [guid])
select rows.n.query('.') as trans, newid() id
from @p.nodes('/Translation') rows(n)
set @no = scope_identity()
set @i =1
while @i <= @no
begin
select @guid = [guid],
@t = t
from @trans
where id = @i
insert @result
([guid], language, [text] )
select @guid,
rows.n.value('(@language)[1]', 'nvarchar(max)'),
rows.n.value('(@text)[1]', 'nvarchar(max)')
from @t.nodes('/Translation/Entry') rows(n)
set @i = @i +1
end
select * from @result
答案 2 :(得分:0)
我写这段代码,不是很好的工作,但它正在发挥作用。
declare @p xml
set @p = '<Root>
<Translation>
<Entry language ="ES" text = "Alsace"/>
<Entry language ="DE" text = "Elsass"/>
<Entry language ="EN" text = "Alsace"/>
</Translation>
<Translation>
<Entry language ="ES" text = "Brittany"/>
<Entry language ="DE" text = "Bretagne"/>
<Entry language ="EN" text = "Brittany"/>
</Translation>
</Root>'
Declare @n int
set @n = 1 -- counter for transaction nodes in xml
DECLARE @test xml -- to hold complete transaction node
While @n <= 2 -- while loop starts
BEGIN
SET @test = ( select @p.query('/Root/Translation[sql:variable("@n")]') )
SELECT
@n as [Transaction],
a.b.value('Entry[1]/@language','varchar(10)') AS [Language],
a.b.value('Entry[1]/@text','varchar(10)') AS [Text]
FROM @test.nodes('Translation') a(b)
select @n as [Transaction] ,a.b.value('Entry[2]/@language','varchar(10)') AS [Language],
a.b.value('Entry[2]/@text','varchar(10)') AS [Text]
FROM @test.nodes('Translation') a(b)
SELECT
@n as [Transaction],
a.b.value('Entry[3]/@language','varchar(10)') AS [Language],
a.b.value('Entry[3]/@text','varchar(10)') AS [Text]
FROM @test.nodes('Translation') a(b)
SET @n = @n + 1 -- counter for transaction nodes in xml
END -- loop ended
Output:
translation_id, lanuage, text
---------------------------------
1,ES, Alsace
1,DE, Elsass
1,EN, Alsace
2,ES , Brittany
2,DE, Bretagne
2,EN Brittany