如果您正在寻找一个TSQL解决方案,并且您的结果表格应该如下所示的模式:
| DISMISS_SETTING | SHOW_SETTING | DEFAULT_SETTING |
|
| DEFAULT | DEFAULT | DEFAULT |
你应该使用我接下来描述的一组脚本。首先,你需要创建动态存储过程,该存储过程构建动态查询,使你有可能将数据插入到表中的列中,这些列的名称在运行时(XML解析的时间)是未知的:
create procedure mysp_update (@table_name nvarchar(50), @column_name nvarchar(50), @column_value nvarchar(50))
as
begin
declare @rows_count int
declare @query nvarchar(500)
declare @parm_definition nvarchar(100)
set @query = N'select @rows_count = count(1) from ' + quotename(@table_name)
exec sp_executesql @query, N'@rows_count INT OUTPUT', @rows_count OUTPUT
if @rows_count = 0
set @query = N'insert into ' + quotename(@table_name) + N'(' + quotename(@column_name) + N') values (@column_value)'
else
set @query = N'update ' + quotename(@table_name) + N'set ' + quotename(@column_name) + N' = @column_value'
set @parm_definition = N'@column_value nvarchar(50)'
exec sp_executesql @query, @parm_definition, @column_value = @column_value
end
go
接下来,使用这个XQuery / SQL语句从XML中提取你要查找的信息:
declare @data xml = N'<properties>
<property>
<name>DISMISS_SETTING</name>
<value>DEFAULT</value>
</property>
<property>
<name>SHOW_SETTING</name>
<value>DEFAULT</value>
</property>
<property>
<name>DEFAULT_SETTING</name>
<value>DEFAULT</value>
</property>
</properties>'
declare @T table(id int identity, name nvarchar(50), value nvarchar(50))
insert into @T(name, value)
select
x.value(N'(name)[1]', N'nvarchar(50)'),
x.value(N'(value)[1]', N'nvarchar(50)')
from
@data.nodes(N'/properties/property') AS XTbl(x)
接着,把数据对 [名称,值] 提取出来,并存储在表变量 @T
中。最后,遍历此类临时元数据,并将值插入到主表的适当列名中:
declare @name nvarchar(50), @value nvarchar(50), @current_id int = 1
select @name = name, @value = value
from @T where id = @current_id
while @@rowcount = 1
begin
exec mysp_update N'TableName', @name, @value
set @current_id = @current_id + 1
select @name = name, @value = value
from @T where id = @current_id
end
提供的解决方案允许您在XML中拥有可变数量的节点,而无需任何特定顺序。
请注意,从XML中提取数据并插入到主表中的逻辑可以包装在其他存储过程中,例如
mysp_xml_update (@data xml)
,然后以以下简洁的方式执行:
exec mysp_xml_update N'<properties>....</properties>
。
尽管如此,请使用
SQL Fiddle尝试代码。
更新:
根据评论中的要求 - 应该执行一个大的更新,而不是逐列更新。为此,
mysp_update
应该以以下方式进行修改:
create type HashTable as table(name nvarchar(50), value nvarchar(50))
go
create procedure mysp_update (@table_name nvarchar(50), @set HashTable readonly)
as
begin
declare @columns varchar(max)
select @columns = COALESCE(@columns + ', ', '') + quotename(name) from @set
declare @values varchar(max)
select @values = COALESCE(@values + ', ', '') + quotename(value, '''') from @set
declare @query nvarchar(500)
set @query = N'delete from ' + quotename(@table_name)
exec sp_executesql @query
set @query = N'insert into ' + quotename(@table_name) + N'(' + @columns + N') values (' + @values + N')'
exec sp_executesql @query
end
go
declare @T table(id int identity, name nvarchar(50), value nvarchar(50))
需要更改为declare @T HashTable
等),但应该很简单。 - jwaliszko