如果你正在尋找一個解決方案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
而不是一次處理一條記錄,有沒有辦法做到這一點,而不必迭代我的數據庫中的每條記錄? –