1

毎日新しいデータをロードするテーブルと、そのテーブルへの変更の履歴を含む別のテーブルがあります。データが最後にロードされてからデータが変更されているかどうかを確認する最良の方法は何ですか?

たとえば、さまざまな国の戦略を含むテーブル@aがあり、テーブル@bはテーブル@aに加えられた変更を追跡します。checksum()を使用して、変更可能なフィールドをハッシュし、既存のハッシュが新しいハッシュと異なる場合はそれらをテーブルに追加できます。ただし、MSDNは、「衝突」が発生する可能性があるため、これは良い考えではないと考えています。たとえば、2つの異なる値が同じチェックサムにマップされます。

チェックサムのMSDNリンク http://msdn.microsoft.com/en-us/library/aa258245(v=SQL.80).aspx

サンプルコード:

declare @a table
(
    ownerid bigint
    ,Strategy varchar(50)
    ,country char(3)
)
insert into @a
select 1,'Long','USA'

insert into @a
select 2,'Short','CAN'

insert into @a
select 3,'Neutral','AUS'

declare @b table
(
    Lastupdated datetime
    ,ownerid bigint
    ,Strategy varchar(50)
    ,country char(3)

)

insert into @b
(
    Lastupdated
    ,ownerid
    ,strategy
    ,country
)
select 
    getdate()
    ,a.ownerid
    ,a.strategy
    ,a.country
from @a a left join @b b
    on a.ownerid=b.ownerid
where
    b.ownerid is null

select * from @b

--get a different timestamp
waitfor delay '00:00:00.1'

--change source data
update @a 
set strategy='Short'
where ownerid=1

--add newly changed data into 
insert into @b
select 
    getdate()
    ,a.ownerid
    ,a.strategy
    ,a.country
from 
    (select *,checksum(strategy,country) as hashval from @a) a 
    left join 
    (select *,checksum(strategy,country) as hashval from @b) b
    on a.ownerid=b.ownerid
where 
    a.hashval<>b.hashval

select * from @b
4

3 に答える 3

1

問題に対して別のアプローチを使用する場合は、変更を確認する必要はありません。

マスターテーブルで、のトリガーを作成します。これはINSERT、テーブルに書き込むことで変更UPDATEDELETE追跡します@b

インターネットで「SQL監査テーブル」を検索すると、プロセスを説明する多くのページが見つかります。たとえば、次のようになります。SQLServerデータベースに単純なトリガーベースの監査を追加する

于 2012-05-04T09:29:38.570 に答える
1

を使用してクエリを作成するのはどうEXCEPTですか?両方のテーブルのクエリを記述しEXCEPT、それらの間に追加するだけです。

(SELECT * FROM table_new) EXCEPT (SELECT * FROM table_old) 

table_new結果は、に含まれていないtable_old(つまり、更新または挿入された)エントリになります。

注:から最近削除された行を取得table_oldするには、クエリの順序を逆にすることができます。

于 2012-05-04T10:01:58.693 に答える
1

@newenglanderのおかげで、変更された行を見つけるためにEXCEPTを使用することができました。@Tonyが言ったように、複数の変更がどのように機能するかはわかりませんが、チェックサムの代わりにExceptを使用するように作り直された同じサンプルコードがあります

declare @a table
(
    ownerid bigint
    ,Strategy varchar(50)
    ,country char(3)
)
insert into @a
select 1,'Long','USA'

insert into @a
select 2,'Short','CAN'

insert into @a
select 3,'Neutral','AUS'

declare @b table
(
    Lastupdated datetime
    ,ownerid bigint
    ,Strategy varchar(50)
    ,country char(3)

)

insert into @b
(
    Lastupdated
    ,ownerid
    ,strategy
    ,country
)
select 
    getdate()
    ,a.ownerid
    ,a.strategy
    ,a.country
from @a a left join @b b
    on a.ownerid=b.ownerid
where
    b.ownerid is null

select * from @b

--get a different timestamp
waitfor delay '00:00:00.1'

--change source data
update @a 
set strategy='Short'
where ownerid=1



--add newly changed data using EXCEPT
insert into @b 
select getdate(),
    ownerid,
    strategy,
    country
from 
(
    (
    select 
        ownerid
        ,strategy
        ,country 
    from @a changedtable
    ) 
    EXCEPT 
    (
    select 
        ownerid
        ,strategy
        ,country 
    from @b historicaltable
    )
) x

select * from @b
于 2012-05-15T19:24:27.533 に答える