1

鉴于我将这样的信息存储在 XML 列中,其架构如下所示 -

<root>
  <Setting>
     <Name>BookingDate</Name>
     <Value>01 Jan 2013</Value>
  </Setting>
  <Setting>
     <Name>Price</Name>
     <Value>23.66</Value>
  </Setting>
</root>

我可以编写一个查询,将“名称”提取为列,将“设置”提取为行值,这样它们看起来就好像我对该行做了一个简单的选择,即

行ID | 正常列1 | 正常列2 | 预订日期 | 价格
-------------------------------------------------- ------------
 1 | X | 是 | 2013 年 1 月 1 日 | 23.66

我可以做一个静态查询,但是当项目被添加到 XML 中时,我如何编写一个返回更多结果的查询?我想把它放在一个带有 Select * 的视图中,这样当人们向 XML 添加更多信息时,更多的结果将从视图上的查询中显示出来。

然后我可以索引这个模式,甚至可以到达输入的点。目的是存储未知的信息。

有什么想法吗?

4

1 回答 1

1

您需要动态构建查询以获得动态数量的列,并确定需要解析 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

于 2013-01-13T18:01:30.617 回答