Se siete alla ricerca di una soluzione TSQL e se il vostro tavolo risultato dovrebbe apparire così indicato sul schemat di seguito:
| DISMISS_SETTING | SHOW_SETTING | DEFAULT_SETTING |
|-----------------|--------------|-----------------|
| DEFAULT | DEFAULT | DEFAULT |
si dovrebbe usare insieme di script, verrà descritto in un attimo. Inizialmente è necessario creare una stored procedure dinamica che costruisca query dinamiche - ti dà la possibilità di inserire i tuoi dati nella tabella sotto tali colonne, i cui nomi non sono noti fino al runtime (il tempo del tuo parsing 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
Avanti, utilizzare questa istruzione XQuery/SQL per estrarre (da XML) le informazioni che state cercando:
-- 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)
Dopo di che, le coppie di dati estratti [name, value] sono memorizzati nella tabella delle variabili @T
. Infine, iterare su tali metadati temporanea e inserire valori in appositi nomi delle colonne della vostra tabella principale:
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
soluzione presentata permette di avere il numero mutevole di nodi nel XML, forniti senza alcun ordine specifico.
Si noti che la logica responsabile dell'estrazione dei dati da XML e l'inserimento nella tabella principale, può essere racchiusa all'interno di una stored procedure aggiuntiva, ad es. mysp_xml_update (@data xml)
e quindi eseguito nel seguente modo pulito: exec mysp_xml_update N'<properties>....</properties>
.
Tuttavia, provare il codice utilizzando SQL Fiddle.
UPDATE:
Come richiesto nel commento - un unico grande aggiornamento deve essere eseguito, invece di colonna di aggiornamento in sequenza da colonna. A tale scopo, è necessario modificare mysp_update
ad es. nel modo seguente:
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
Jaroslaw, questo è grande. C'è un modo semplice per farlo senza usare la variabile XML? Ad esempio, ho righe su righe di XML da elaborare. –
@Dave L. Ciao, piacere di sentirlo. Purtroppo temo di non capire veramente la domanda in commento - puoi approfondire un po 'di più cosa stai cercando di ottenere? – jwaliszko
invece di elaborare un record alla volta, c'è un modo per farlo senza dover scorrere tutti i record nel mio database? –