1

以下のようなスキーマを持つ XML 列にこのように格納された情報があるとします -

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

「名前」を列として抽出し、「設定」を行の値として抽出するクエリを作成して、その行で単純な選択を行ったかのように表示することはできますか?

行 ID | NormalColumn1 | NormalColumn2 | 予約日 | 価格
-------------------------------------------------- -----------
 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 |

アップデート:

上記のコメントから、すべての可能な設定名を追跡するテーブルがすでにあるようです。その場合は、のトリガーは必要ありませんSettingsSettingテーブルを更新した後にビューが再構築されていることを確認するだけの場合は、実際にはトリガーをオンにする必要はありませんSetting

于 2013-01-13T18:01:30.617 に答える