Bạn có thể làm một cái gì đó giống như ví dụ này, nơi tôi đang đăng nhập thay đổi cho một bảng lịch sử giao dịch:
create table dbo.action
(
id int not null primary key ,
description varchar(32) not null unique ,
)
go
insert dbo.action values(1 , 'insert')
insert dbo.action values(2 , 'update')
insert dbo.action values(3 , 'delete')
go
create table dbo.foo
(
id int not null identity(1,1) primary key ,
value varchar(200) not null unique ,
)
go
create table dbo.foo_history
(
id int not null ,
seq int not null identity(1,1) ,
action_date datetime not null default(current_timestamp) ,
action_id int not null foreign key references dbo.action (id),
old_value varchar(200) null ,
new_value varchar(200) null ,
primary key nonclustered (id , seq) ,
)
go
create trigger foo_update_01 on dbo.foo for insert, update , delete
as
set nocount on
set xact_abort on
set ansi_nulls on
set concat_null_yields_null on
--
-- record change history
--
insert dbo.foo_history
(
id ,
action_id ,
old_value ,
new_value
)
select id = coalesce(i.id , d.id) ,
action_id = case
when i.id is not null and d.id is null then 1 -- insert
when i.id is not null and d.id is not null then 2 -- update
when i.id is null and d.id is not null then 3 -- delete
end ,
old_value = d.value ,
new_value = i.value
from inserted i
full join deleted d on d.id = i.id
go
Nhưng bạn có thể sử dụng cùng một loại kỹ thuật, pha trộn nó lên một chút và vượt qua toàn bộ bộ các giá trị cho một thủ tục được lưu trữ, như tôi làm trong ví dụ sau (sử dụng lược đồ bảng ở trên).
Đầu tiên, tạo một stored procedure mà hy vọng một bảng tạm thời đặc biệt để tồn tại trong thời gian chạy, như sau:
--
-- temp table must exist or the stored procedure won't compile
--
create table #foo_changes
(
id int not null primary key clustered ,
action_id int not null ,
old_value varchar(200) null ,
new_value varchar(200) null ,
)
go
--
-- create the stored procedure
--
create procedure dbo.foo_changed
as
--
-- do something useful involving the contents of #foo_changes here
--
select * from #foo_changes
return 0
go
--
-- drop the temp table
--
drop table #foo_changes
go
Một khi bạn đã làm điều đó, tạo ra một kích hoạt sẽ tạo ra và cư trú trong bảng temp mong đợi của quy trình được lưu trữ và sau đó thực hiện quy trình được lưu trữ:
create trigger foo_trigger_01 on dbo.foo for insert, update , delete
as
set nocount on
set xact_abort on
set ansi_nulls on
set concat_null_yields_null on
--
-- create the temp table. This temp table will be in scope for any stored
-- procedure executed by this trigger. It will be automagickally dropped
-- when trigger execution is complete.
--
-- Any changes made to this table by a stored procedure — inserts,
-- deletes or updates are, of course, visible to the trigger upon return
-- from the stored procedure.
--
create table #foo_changes
(
id int not null primary key clustered ,
action_id int not null ,
old_value varchar(200) null ,
new_value varchar(200) null ,
)
--
-- populate the temp table
--
insert #foo_changes
(
id ,
action_id ,
old_value ,
new_value
)
select id = coalesce(i.id , d.id) ,
action_id = case
when i.id is not null and d.id is null then 1 -- insert
when i.id is not null and d.id is not null then 2 -- update
when i.id is null and d.id is not null then 3 -- delete
end ,
old_value = d.value ,
new_value = i.value
from inserted i
full join deleted d on d.id = i.id
--
-- execute the stored procedure. The temp table created above is in scope
-- for the stored procedure, so it's able to access the set of changes from
-- the trigger.
--
exec dbo.foo_changed
go
Đó là tất cả về nó. Thật đơn giản, thật dễ dàng, nó hoạt động cho các bộ thay đổi có kích thước bất kỳ. Và, nó an toàn, không có điều kiện chủng tộc hoặc va chạm với những người dùng khác trong hệ thống.