Nếu bạn đang tìm kiếm một giải pháp TSQL và nếu tôi bảng kết quả của bạn sẽ trông như thế này được hiển thị trên schemat dưới đây:
| DISMISS_SETTING | SHOW_SETTING | DEFAULT_SETTING |
|-----------------|--------------|-----------------|
| DEFAULT | DEFAULT | DEFAULT |
bạn nên sử dụng thiết lập các kịch bản tôi sẽ mô tả trong một khoảnh khắc. Ban đầu, bạn cần tạo thủ tục lưu trữ động để tạo truy vấn động - nó cung cấp cho bạn khả năng chèn dữ liệu của bạn vào bảng dưới các cột như vậy, tên không được biết cho đến khi chạy (thời gian phân tích cú pháp XML của bạn):
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
Tiếp theo, sử dụng câu lệnh XQuery/SQL này để trích xuất (từ XML) thông tin mà bạn đang tìm kiếm:
-- 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)
Sau đó, cặp dữ liệu chiết xuất [tên, giá trị] được lưu trữ trong bảng biến @T
. Cuối cùng, lặp qua siêu dữ liệu tạm thời như vậy và chèn giá trị trong tên thích hợp cột của bảng chính của bạn:
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
giải pháp trình bày cho phép bạn có số có thể thay đổi các nút trong XML, với điều kiện không có thứ tự cụ thể.
Lưu ý rằng logic chịu trách nhiệm về trích xuất dữ liệu từ XML và chèn vào bảng chính, có thể được bao bọc trong quy trình được lưu trữ bổ sung, ví dụ: mysp_xml_update (@data xml)
và sau đó được thực hiện theo cách sạch sẽ sau: exec mysp_xml_update N'<properties>....</properties>
.
Tuy nhiên, hãy tự mình thử mã sử dụng SQL Fiddle.
UPDATE:
Theo yêu cầu trong các bình luận - một bản cập nhật lớn nên được thực hiện thay vì cột liên tục cập nhật theo cột. Vì mục đích đó, cần phải sửa đổi mysp_update
ví dụ: theo cách sau:
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, đây là tuyệt quá. Có cách nào dễ dàng để làm điều này mà không sử dụng biến XML? Ví dụ, tôi có các hàng trên các hàng XML để xử lý. –
@Dave L. Xin chào, rất vui được nghe điều đó. Thật không may tôi sợ tôi không thực sự hiểu được câu hỏi trong bình luận - bạn có thể xây dựng thêm một chút những gì bạn đang cố gắng để đạt được? – jwaliszko
thay vì xử lý một bản ghi tại một thời điểm, có cách nào để thực hiện việc này mà không phải lặp qua từng bản ghi trong cơ sở dữ liệu của tôi không? –