--增加一个标识列
alter table T_Record add ID int identity(1,1)
--创建触发器
create trigger tri_cards
on dbo.T_cards
for insert ,update
as
declare
@Cardname varchar(10),
@lastCardname varchar(10),
@beforeChange int,
@AfterChange int,
@user varchar(10),
@lastuser varchar(10),
@ID int,
@num int,
@lastnum int
begin
----------------------------------取得插入的卡号,拥有人
select @Cardname=游戏卡名称,@user=拥有人 from inserted
---------------------------------取得对应卡名的最后一次更新的后数量,
select @beforechange=[出/入库后数量],@id=ID ,@lastnum=[出/入库数量] from T_Record
where ID in
(select Max(ID) from T_Record where 游戏卡名称=@cardname)
--------------------------------判断是存入还是取出
if left(cast(@lastnum as char(10)),1)<>'-'
begin
set @lastuser='system'
end
else
begin
set @lastuser='出库'
end
-----------------------判断出入库表中最后一条记录的游戏卡名称是否是刚插入的游戏卡名称
if exists(select 游戏卡名称 from T_Record where 游戏卡名称=@Cardname and id
in (select max(id) from T_Record))
begin
----------------------------入库,且最后一个记录是入库时,更新
if @user='system' and @lastuser='system'
begin
update T_Record set [出/入库数量]=[出/入库数量]+1,
[出/入库后数量]=[出/入库后数量]+1 where id=@id
end
----------------------------入库,最后一个记录不是入库时,插入记录
else if @user='system' and @lastuser<>'system'
begin
insert into T_Record(游戏卡名称,[出/入库前数量],[出/入库数量],
[出/入库后数量]) values(@cardname,@BeforeChange,1,@BeforeChange+1)
end
-----------------------------出库,最后一个记录是入库时,插入
else if @user<>'system' and @lastuser='system'
begin
---------------------------------出库前数量不够,出错
if @BeforeChange=0
begin
print '没有出/入库预期的数量'
end
else
begin
insert into T_Record(游戏卡名称,[出/入库前数量],[出/入库数量],
[出/入库后数量]) values(@cardname,@BeforeChange,-1,@BeforeChange-1)
end
end
------------------------------出库,最后一个记录不是入库时,更新
else if @user<>'system' and @lastuser<>'system'
begin
if @BeforeChange=0
begin
print '没有出/入库预期的数量'
end
else
begin
update T_Record set [出/入库数量]=[出/入库数量]-1,
[出/入库后数量]=[出/入库后数量]-1 where id=@id
end
end
end
-----------------------------不存在相应的记录时
else
begin
----------------------------入库时
if @user='system'
begin
insert into T_Record(游戏卡名称,[出/入库前数量],[出/入库数量],
[出/入库后数量]) values(@cardname,0,1,01)
end
else
----------------------------出库时,出错
begin
print '没有出/入库预期的数量'
end
end
end
--测试1
insert into T_Cards select 'A','c0001','c0001','system','system'
insert into T_Cards select 'A','c0002','c0002','system','system'
insert into T_Cards select 'A','c0003','c0003','system','system'
insert into T_Cards select 'A','c0004','c0004','system','system'
--你也可以一条条插入测试
--结果:
ID 游戏卡名称 出/入库前数量 出入库数量 出/入库数量
1 A 0 4 4
--测试2
update T_Cards set 拥有人='p1' where 卡号='c0001'
update T_Cards set 拥有人='p1' where 卡号='c0003'
--结果:如果ID是添加上去的,ID显示在最后
ID 游戏卡名称 出/入库前数量 出入库数量 出/入库数量
1 A 0 4 4
2 A 4 -2 2
--测试3
insert into T_Cards select 'B','B0001','B0001','system','system'
insert into T_Cards select 'B','B0002','B0002','system','system'
insert into T_Cards select 'B','B0003','B0003','system','system'
insert into T_Cards select 'B','B0004','B0004','system','system'
update T_Cards set 拥有人='p2' where 卡号='B0001'
update T_Cards set 拥有人='p2' where 卡号='B0003'
--结果
ID 游戏卡名称 出/入库前数量 出入库数量 出/入库数量
1 A 0 4 4
2 A 4 -2 2
3 B 0 4 4
4 B 4 -2 2
create trigger clk
on T_Cards
for update
as
declare @a varchar(8000)
declare @b int
declare @c int
declare @d int
if update(某类卡数量字段)
begin
select @a=类型 from inserted
select @b=游戏卡数量 from deleted --A类卡入库前的数量
select @c=游戏卡数量 from inserted --入库后的数量
select @d=@c-@b --入库的数量
insert into T_Record
values(@a,@b,@d,@c)
if @@error<>0 ----为了提高系统的完整性与一致性,最好加上这个错误判断语句.
begin
rollback transaction
return
end
end
go
**************************************************************************************
在上面的语句中
select @a=类型 from inserted --将你要增加数量的游戏卡类型赋到@a变量中.
select @b=游戏卡数量 from deleted --将A类卡入库前的数量赋到@b变量中.
select @c=游戏卡数量 from inserted --将A类卡入库后的数量赋到@c变量中
select @d=@c-@b --将A类卡入库的数量赋到@d变量中
针对你的问题:
"对了,我补充一下,游戏卡出库并不需要在T_Cards表中将游戏卡记录删除,而是将其中一个字段(Owner)的值改变一下就可以了。出库和入库都使用同一个触发器吗?谢谢"
说明:这个触发器并没有在T_Cards表中将游戏卡记录人为的显示的删除,上面出现的deleted和inserted只是支持触发器工作的临时表(是在系统内部生成的).
我可以这样跟你解释:
对数据的更新,在DBMS中实际上对数据进行的是两步操做:
1:先删除你要更新的旧记录
2:然后再将你更新后的新记录插入到数据表中
而触发器恰恰显示的证明了这一点.
如果你的表设计合理的话:先做一个简单的假设:
你的T_Cards的表的结构为:
(类型 varchar(8000) primary key,游戏卡数量 int )
你的T_Record表的结构为:
(类型 varchar(8000),A类卡入库前的数量 int,入库的数量 int,入库后的数量 int)
针对这种情况:
在你的T_Cards表上创建触发器:
create trigger clk
on T_Cards
for update
as
declare @a varchar(8000)
declare @b int
declare @c int
declare @d int
if update(某类卡数量字段)
begin
select @a=类型 from inserted
select @b=游戏卡数量 from deleted --@b为A类卡入库前的数量
select @c=游戏卡数量 from inserted --@c为A类卡入库后的数量
select @d=@c-@b --@d为A类卡入库的数量
insert into T_Record
values(@a,@b,@d,@c)
if @@error<>0 ----为了提高系统的完整性与一致性,最好加上这个错误判断语句.
begin
rollback transaction
return
end
end
go
这种思路(方法)完全可以解决你的问题,不过具体的表设计还要楼主根据具体情况来设计.