我有以下类型的xml
<root>
<row1 invoice_number="WEDRT" vendor="Telekm" amount="233" status="1" created_date="42590" />
<row2 invoice_number="MSFDRT" vendor="ARS" amount="344" status="1" created_date="42955" />
</root>
这个xml是动态生成的。通过动态我的意思是在编写sql代码来解析它时,我不知道有多少行和属性。 可以有多达100,000行和用户想要的属性。我甚至不知道属性的名称。
是否可以通过从此xml中生成以下类型的结果将其放入临时表中?
Invoice_number Vendor amount status created_Date
WEDRT TELEKOM 233 1 42590
MSFDRT ARS 344 1 42955
我试过以下
DECLARE
@xml XML,
@Columns VARCHAR(MAX)
SET @xml = '
<root>
<row1 invoice_number="WEDRT" vendor="Telekm" amount="233" status="1" created_date="42590" />
<row2 invoice_number="MSFDRT" vendor="ARS" amount="344" status="1" created_date="42955" />
</root>
'
BEGIN
SET NOCOUNT ON;
DECLARE @COUNT INT, @COUNTER INT, @TQUERY VARCHAR(2000), @SELECT VARCHAR(MAX), @VALUES VARCHAR(MAX)
SELECT * INTO #TEMPTABLE
FROM(
SELECT
CAST(x.v.query('local-name(.)') AS VARCHAR(100)) As AttributeName,
v.value('.' , 'VARCHAR(100)') AS Value
FROM @XML.nodes('//@*') x(v)
) A
SELECT * FROM #TEMPTABLE
DROP TABLE #TEMPTABLE
END
它给出了如下表中xml
中2行的结果AttributeName Value
invoice_number WEDRT
vendor Telekom
amount 233
status 1
created_Date 42590
invoice_number MSFDRT
vendor ARS
amount 344
status 1
created_Date 42955
答案 0 :(得分:4)
我修改了你的查询,希望这有帮助。
DECLARE @xml XML,
@Columns VARCHAR(MAX)
SET @xml = '
<root>
<row1 invoice_number="WEDRT" vendor="Telekm" amount="233" status="1" created_date="42590" />
<row2 invoice_number="MSFDRT" vendor="ARS" amount="344" status="1" created_date="42955" />
</root>
'
BEGIN
SET NOCOUNT ON;
DECLARE @COUNT INT, @COUNTER INT, @TQUERY VARCHAR(2000), @SELECT VARCHAR(MAX), @VALUES VARCHAR(MAX)
SELECT * INTO #TEMPTABLE
FROM(
SELECT CAST(x.v.query('local-name(.)') AS VARCHAR(100)) As AttributeName,
x.v.value('.' , 'VARCHAR(100)') AS [Value],
CAST(x.v.query('local-name(..)') AS VARCHAR(100)) As RowNumber
FROM @XML.nodes('//*//@*') x(v)
) A
DECLARE @t TABLE (AttributeName nvarchar(max), r int)
DECLARE @sql nvarchar(max),
@col nvarchar(max)
INSERT INTO @t
SELECT DISTINCT AttributeName,
ROW_NUMBER() OVER(PARTITION BY RowNumber ORDER BY RowNumber) as r
FROM #TEMPTABLE
SELECT @col = (
SELECT ','+QUOTENAME(AttributeName)
FROM @t
ORDER BY r
FOR XML PATH('')
)
SELECT @sql = N'
SELECT *
FROM #TEMPTABLE t
PIVOT (
MAX([Value]) FOR AttributeName IN ('+STUFF(@col,1,1,'')+')
) as pvt'
EXEC sp_executesql @sql
DROP TABLE #TEMPTABLE
END
输出:
RowNumber invoice_number vendor amount status created_date
row1 WEDRT Telekm 233 1 42590
row2 MSFDRT ARS 344 1 42955
主要思想是动态调整结果。要删除RowNumber
列,您可以使用SELECT '+STUFF(@col,1,1,'')+'
代替'SELECT *
部分
答案 1 :(得分:0)
你走在正确的轨道上。只需要更改所有元素而不是所有属性:
declare @x xml = '<root>
<row1 invoice_number="WEDRT" vendor="Telekm" amount="233" status="1" created_date="42590" />
<row2 invoice_number="MSFDRT" vendor="ARS" amount="344" status="1" created_date="42955" />
</root>';
select t.c.value('local-name(.)', 'sysname') as [NodeName],
t.c.value('./@invoice_number', 'varchar(50)') as [InvoiceNumber],
t.c.value('./@vendor', 'varchar(50)') as [Vender],
t.c.value('./@amount', 'money') as [Amount],
t.c.value('./@status', 'int') as [Status],
t.c.value('./@created_date', 'int') as [CreatedDate]
from @x.nodes('/root[1]/*') t(c);
我已将节点名称添加为第一列,以防您可能需要它。如果您没有,请将其从查询中删除。