再做这样的触发器(新增和修改类似): create trigger t_del on TABLE_A for DELETE as begin insert into 日志记录(操作时间,操作,用户,id,name,price) select getdate() as 操作时间,'删除' as 操作,(select top 1 用户名 from 状态) as 用户,id,name,price from deleted end
--在table_a中加一列userid--登陆用户名--更新触发器 TABLE_A(id,name,price) create trigger tr_update on table_a for update declare @userA varchar(20) --登陆用户名 declare @oldval decimal(9,2),@newval decimal(9,2) select @userA = userid,@newval = price from inserted select @oldval = price from deleted if (select price from inserted) <> (select price from deleted) insert table_B (USER,ACTION,TIME) values (@userA,'修改价格,原值为' + convert(varchar(12),@oldval) + ',修改后为' + convert(varchar(12),@newval),getdate())
TO FANMB: 加入登陆用户名,是不是我每次改动一记录的时候,先改要改动该记录USER_ID列的值为登陆名? 这样的话是不是会增加很多额外的开销! 不知道我说的清楚不清楚: 用户SYS登陆---》修改记录1001-------》先修改TABLEA的USERID列为SYS,---》触发器运行 如果删除也同例, 那么增加呢?没有记录怎么传USEID呢?
好象我试过了TRIGGER不能放在存储过程中!
我觉得你写存储过程比较方便!给你一个看看/*修改存储过程 上传参数为:质量报告单号码 修改后的重量 修改后的备注*/ CREATE PROCEDURE BP_PayMent_XG @vc_PayMentNO Char(11), @de_RRecWeight decimal(18,3), @vc_Re VarChar(1000), @si_Operator SmallInt AS Begin Tran Declare @Si_Auditing SmallInt Declare @de_BegWeight decimal(18,3) Set @si_Auditing = (Select si_Auditing From materialPayMent Where vc_PayMentNO=@vc_PayMentNO) Set @de_BegWeight = (Select de_RecWeight From materialPayMent Where vc_PayMentNO=@vc_PayMentNO) If @si_Auditing<>0 Begin RollBack Tran Return(2005) --统计你没有权限修改这条数据 End Insert INTO MaterialLog (si_Operator,vc_content) Values (@si_Operator,'将原来数量: '+Cast(@de_BegWeight As VarChar(15))+ '修改为:' + Cast(@de_RRecWeight As VarChar(15))+' 表MeterialPayMent的vc_PayMentNO为:'+@vc_PayMentNO) If @@Error<>0 Begin RollBack Tran Return(2007) --修改时写入日志表出错,请重试 End Update MaterialPayMent Set de_RecWeight=@de_RRecWeight,DT_DateTime=Getdate(),vc_ReMark=@vc_Re Where vc_PayMentNO=@vc_PayMentNO If @@Error<>0 Begin RollBack Tran Return(2006) --统计修改PayMent表中的数据出错,请重试! End Commit Tran Return(0) GO
create trigger tri_name on table_a for update asbegin declare @id_i int declare @price_i float declare @price_d float select @id_i = id,@price_i = price from inserted select @price_d = price from deleted if @id_i <> @price_d begin insert into table_b(USER,ACTION,TIME) values(system_user,修改后的价格,getdate()) endend go
create trigger t_del on TABLE_A
for DELETE
as
begin
insert into 日志记录(操作时间,操作,用户,id,name,price)
select getdate() as 操作时间,'删除' as 操作,(select top 1 用户名 from 状态) as 用户,id,name,price from deleted
end
TABLE_A(id,name,price)
create trigger tr_update on table_a
for update
declare @userA varchar(20) --登陆用户名
declare @oldval decimal(9,2),@newval decimal(9,2)
select @userA = userid,@newval = price from inserted
select @oldval = price from deleted
if (select price from inserted) <> (select price from deleted)
insert table_B (USER,ACTION,TIME) values
(@userA,'修改价格,原值为' + convert(varchar(12),@oldval)
+ ',修改后为' + convert(varchar(12),@newval),getdate())
加入登陆用户名,是不是我每次改动一记录的时候,先改要改动该记录USER_ID列的值为登陆名?
这样的话是不是会增加很多额外的开销!
不知道我说的清楚不清楚:
用户SYS登陆---》修改记录1001-------》先修改TABLEA的USERID列为SYS,---》触发器运行
如果删除也同例,
那么增加呢?没有记录怎么传USEID呢?
CREATE PROCEDURE BP_PayMent_XG
@vc_PayMentNO Char(11),
@de_RRecWeight decimal(18,3),
@vc_Re VarChar(1000),
@si_Operator SmallInt
AS
Begin Tran
Declare @Si_Auditing SmallInt
Declare @de_BegWeight decimal(18,3)
Set @si_Auditing = (Select si_Auditing From materialPayMent Where vc_PayMentNO=@vc_PayMentNO)
Set @de_BegWeight = (Select de_RecWeight From materialPayMent Where vc_PayMentNO=@vc_PayMentNO)
If @si_Auditing<>0
Begin
RollBack Tran
Return(2005) --统计你没有权限修改这条数据
End
Insert INTO MaterialLog (si_Operator,vc_content) Values (@si_Operator,'将原来数量: '+Cast(@de_BegWeight As VarChar(15))+ '修改为:' + Cast(@de_RRecWeight As VarChar(15))+' 表MeterialPayMent的vc_PayMentNO为:'+@vc_PayMentNO)
If @@Error<>0
Begin
RollBack Tran
Return(2007) --修改时写入日志表出错,请重试
End
Update MaterialPayMent Set de_RecWeight=@de_RRecWeight,DT_DateTime=Getdate(),vc_ReMark=@vc_Re
Where vc_PayMentNO=@vc_PayMentNO
If @@Error<>0
Begin
RollBack Tran
Return(2006) --统计修改PayMent表中的数据出错,请重试!
End
Commit Tran
Return(0)
GO
asbegin declare @id_i int
declare @price_i float
declare @price_d float select @id_i = id,@price_i = price from inserted
select @price_d = price from deleted if @id_i <> @price_d
begin
insert into table_b(USER,ACTION,TIME)
values(system_user,修改后的价格,getdate())
endend
go
都是SA用户,如你说的插入后不是变成都是SA做的了,怎么区分呢?
我现在程序已经写好了,UPDATE放在程序里写的,没有用存储过程,象你这样
我的修改,删除,添加都要重新写了,而且如果这样写有一个很大的问题,比如我的表有20个字段,我可能没有修改全部只是修改了一个字节,而他记录了全部的字段,是不是对于数据库体积没有很好的控制!
可以用
if update(字段名)
来判断此字段是否被修改过
可以在触发器主体中的任意位置使用 UPDATE (column)。column是要测试 INSERT 或 UPDATE 操作的列名。该列可以是 SQL Server 支持的任何数据类型。但是,计算列不能用于该环境中。有关更多信息,请参见数据类型。 IF (COLUMNS_UPDATED()) 测试是否插入或更新了提及的列,仅用于 INSERT 或 UPDATE 触发器中。COLUMNS_UPDATED 返回 varbinary 位模式,表示插入或更新了表中的哪些列。COLUMNS_UPDATED 函数以从左到右的顺序返回位,最左边的为最不重要的位。最左边的位表示表中的第一列;向右的下一位表示第二列,依此类推。如果在表上创建的触发器包含 8 列以上,则 COLUMNS_UPDATED 返回多个字节,最左边的为最不重要的字节。在 INSERT 操作中 COLUMNS_UPDATED 将对所有列返回 TRUE 值,因为这些列插入了显式值或隐性 (NULL) 值。可以在触发器主体中的任意位置使用 COLUMNS_UPDATED。
如果必须测试影响到表中前 8 列以外的列的更新时,必须使用 UBSTRING 函数测试由 COLUMNS_UPDATED 返回的适当的位。下例测试影响 Northwind.dbo.Customers 表中的第 3、第 5 或第 9 列的更新。USE Northwind
DROP TRIGGER tr1
GO
CREATE TRIGGER tr1 ON Customers
FOR UPDATE AS
IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))
+ power(2,(5-1)))
AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1)))
)
PRINT 'Columns 3, 5 and 9 updated'
GOUPDATE Customers
SET ContactName=ContactName,
Address=Address,
Country=Country
GO