您需要动态构建查询以获得动态数量的列,并确定需要解析 XML 的每个节点的列,如果表中有相当数量的行,这在服务器上可能会很困难.
我建议您有一个Setting
包含有效设置名称的表,并在触发器中将该表更新为该Settings
表。
要获得反映您拥有的设置的视图,您可以在表上添加一个触发器Setting
来动态更新视图。
SQL小提琴
MS SQL Server 2008 架构设置:
create table Settings
(
RowID int identity primary key,
Settings xml
)
go
create table Setting
(
Name varchar(20) primary key
)
go
create view v_Settings as
select RowID
from Settings
go
create trigger tr_Settings on Settings for insert, update as
with C(Name) as
(
select distinct T.N.value('text()[1]', 'nvarchar(20)')
from inserted as I
cross apply I.Settings.nodes('/root/Setting/Name') as T(N)
)
insert into Setting(Name)
select Name
from C
where C.Name not in (select Name from Setting)
go
create trigger tr_Setting on Setting for insert as
declare @SQL nvarchar(max)
set @SQL = 'alter view v_Settings as ' +
'select S.RowID'+
(
select ',S.Settings.value(''(root/Setting[Name="' +
S.Name +
'"]/Value/text())[1]'', ''varchar(max)'') as '+
quotename(S.Name)
from Setting as S
for xml path(''), type
).value('text()[1]', 'nvarchar(max)')+
' from Settings as S'
exec (@SQL)
查询 1:
insert into Settings values
('<root>
<Setting>
<Name>BookingDate</Name>
<Value>01 Jan 2013</Value>
</Setting>
<Setting>
<Name>Price</Name>
<Value>23.66</Value>
</Setting>
</root>')
select *
from v_Settings
结果:
| ROWID | BOOKINGDATE | PRICE |
-------------------------------
| 5 | 01 Jan 2013 | 23.66 |
查询 2:
insert into Settings values
('<root>
<Setting>
<Name>BookingDate</Name>
<Value>02 Jan 2013</Value>
</Setting>
<Setting>
<Name>PriceX</Name>
<Value>24.66</Value>
</Setting>
</root>')
select *
from v_Settings
结果:
| ROWID | BOOKINGDATE | PRICE | PRICEX |
-----------------------------------------
| 5 | 01 Jan 2013 | 23.66 | (null) |
| 6 | 02 Jan 2013 | (null) | 24.66 |
更新:
从上面的评论看来,您已经有一个表格来记录所有可能的设置名称。如果是这种情况,您不需要在Settings
. Setting
如果您只是确保在更新 table 后重建视图,您实际上不需要触发器Setting
。