如果你正在寻找一个解决方案TSQL,如果我是你的结果表应该是这样下面的schemat所示:
| 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)
-- Get rows count in your table using sp_executesql and an output parameter
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 no rows - insert the first one, else - update existing
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)的信息,你正在寻找:
-- Define XML object based on which insert statement will be later created
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 temporary container
declare @T table(id int identity, name nvarchar(50), value nvarchar(50))
-- Push the extracted nodes values into it
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
-- Fetch first row
select @name = name, @value = value
from @T where id = @current_id
while @@rowcount = 1
begin
-- Execute SP here (btw: SP cannot be executed from select statement)
exec mysp_update N'TableName', @name, @value
-- Fetch next row
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自己尝试编码。
UPDATE:
的要求,在评论 - 一个大的更新应该由列执行的,而不是按顺序更新列。为此目的,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
-- Concatenate names and values (to be passed to insert statement below)
declare @columns varchar(max)
select @columns = COALESCE(@columns + ', ', '') + quotename(name) from @set
declare @values varchar(max)
select @values = COALESCE(@values + ', ', '') + quotename(value, '''') from @set
-- Remove previous values
declare @query nvarchar(500)
set @query = N'delete from ' + quotename(@table_name)
-- Insert new values to the table
exec sp_executesql @query
set @query = N'insert into ' + quotename(@table_name) + N'(' + @columns + N') values (' + @values + N')'
exec sp_executesql @query
end
go
雅罗斯瓦夫,这是大。有没有简单的方法来做到这一点,而不使用XML变量?例如,我有一行处理XML的行。 –
@Dave L.嗨,很高兴听到这一点。不幸的是,我担心我并不真正理解评论中的问题 - 你能详细阐述一下你想达到的目标吗? – jwaliszko
而不是一次处理一条记录,有没有办法做到这一点,而不必迭代我的数据库中的每条记录? –