我有一个像下面这样的xml数据模式。我只需要读取xml数据并将其存储在临时表中。列是动态的(下面的列只是样本),但属性是常量。我期待下面的结果。
BandCode BandDescription BandName Code Country Currency Pay1_11 Pay1_12 Pay1_13 Pay1_14 Pay1_15
123440 Band-A Band1 1234567 Germany US 10000.00 10000.00 10000.00 10000.00 10000.00
123441 Band-B Band2 1234567 Germany US 10000.00 10000.00 10000.00 10000.00 10000.00
示例xml数据
<CookedData>
<row RowNumber="1">
<Column DestinationColumnCode="BandCode" DataType="VARCHAR(3000)" Value="123440"/>
<Column DestinationColumnCode="BandDescription" DataType="VARCHAR(3000)" Value="Band-A"/>
<Column DestinationColumnCode="BandName" DataType="VARCHAR(3000)" Value="Band1"/>
<Column DestinationColumnCode="Code" DataType="VARCHAR(3000)" Value="1234567"/>
<Column DestinationColumnCode="Country" DataType="VARCHAR(3000)" Value="Germany"/>
<Column DestinationColumnCode="Currency" DataType="MONEY" Value="US"/>
<Column DestinationColumnCode="Pay1_11" DataType="MONEY" Value="10000.00"/>
<Column DestinationColumnCode="Pay1_12" DataType="MONEY" Value="10000.00"/>
<Column DestinationColumnCode="Pay1_13" DataType="MONEY" Value="10000.00"/>
<Column DestinationColumnCode="Pay1_14" DataType="MONEY" Value="10000.00"/>
<Column DestinationColumnCode="Pay1_15" DataType="MONEY" Value="10000.00"/>
</row>
<row RowNumber="2">
<Column DestinationColumnCode="BandCode" DataType="VARCHAR(3000)" Value="123441"/>
<Column DestinationColumnCode="BandDescription" DataType="VARCHAR(3000)" Value="Band-B"/>
<Column DestinationColumnCode="BandName" DataType="VARCHAR(3000)" Value="Band2"/>
<Column DestinationColumnCode="Code" DataType="VARCHAR(3000)" Value="1234567"/>
<Column DestinationColumnCode="Country" DataType="VARCHAR(3000)" Value="Germany"/>
<Column DestinationColumnCode="Currency" DataType="MONEY" Value="US"/>
<Column DestinationColumnCode="Pay1_11" DataType="MONEY" Value="10000.00"/>
<Column DestinationColumnCode="Pay1_12" DataType="MONEY" Value="10000.00"/>
<Column DestinationColumnCode="Pay1_13" DataType="MONEY" Value="10000.00"/>
<Column DestinationColumnCode="Pay1_14" DataType="MONEY" Value="10000.00"/>
<Column DestinationColumnCode="Pay1_15" DataType="MONEY" Value="10000.00"/>
</row>
</CookedData>
我已经研究过如何执行此操作,但我找到的示例代码仅适用于静态列。
答案 0 :(得分:1)
您必须动态构建查询。
此代码使用第一行节点/CookedData/row[1]/Column
中的信息来获取列名和数据类型。
这不适用于您的XML,因为您已将money
指定为列Currency
的数据类型。您需要将其更改为其他内容。
declare @SQL nvarchar(max) =
'select '+
(
select ',T.X.value(''Column[@DestinationColumnCode = "'+T.ColName+'"][1]/@Value'','''+T.DataType+''') as '+quotename(T.ColName)
from (
select T.X.value('@DestinationColumnCode', 'nvarchar(128)') as ColName,
T.X.value('@DataType', 'nvarchar(128)') as DataType
from @XML.nodes('/CookedData/row[1]/Column') as T(X)
) as T
for xml path(''), type
).value('substring(text()[1], 2)', 'nvarchar(max)')+' '+
'from @XML.nodes(''/CookedData/row'') as T(X)';
exec sp_executesql @SQL, N'@XML xml', @XML;
动态构建的查询如下所示:
select T.X.value('Column[@DestinationColumnCode = "BandCode"][1]/@Value','VARCHAR(3000)') as [BandCode],
T.X.value('Column[@DestinationColumnCode = "BandDescription"][1]/@Value','VARCHAR(3000)') as [BandDescription],
T.X.value('Column[@DestinationColumnCode = "BandName"][1]/@Value','VARCHAR(3000)') as [BandName],
T.X.value('Column[@DestinationColumnCode = "Code"][1]/@Value','VARCHAR(3000)') as [Code],
T.X.value('Column[@DestinationColumnCode = "Country"][1]/@Value','VARCHAR(3000)') as [Country],
T.X.value('Column[@DestinationColumnCode = "Currency"][1]/@Value','CHAR(2)') as [Currency],
T.X.value('Column[@DestinationColumnCode = "Pay1_11"][1]/@Value','MONEY') as [Pay1_11],
T.X.value('Column[@DestinationColumnCode = "Pay1_12"][1]/@Value','MONEY') as [Pay1_12],
T.X.value('Column[@DestinationColumnCode = "Pay1_13"][1]/@Value','MONEY') as [Pay1_13],
T.X.value('Column[@DestinationColumnCode = "Pay1_14"][1]/@Value','MONEY') as [Pay1_14],
T.X.value('Column[@DestinationColumnCode = "Pay1_15"][1]/@Value','MONEY') as [Pay1_15]
from @XML.nodes('/CookedData/row') as T(X)