A类卡入库前的数量,入库的数量,入库后的数量假设你的表的设计:在你的T_Record中有 类型,A类卡入库前的数量,入库的数量,入库后的数量
T_Cards  T_Record在T_Cards 创建一个触发器create trigger clk
on T_Cards 
for update
as
declare @a varchar(8000)
declare @b int
declare @c int
declare @d int
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)
go

解决方案 »

  1.   

    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)
    end
    go
      

  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
      

  3.   

    你好 General521(dhy) 我以前没做过触发器,所以有些看不懂,你能不能稍为我解释一下如下语句?万分感谢select @a=类型 from inserted
    select @b=游戏卡数量 from deleted    --A类卡入库前的数量
    select @c=游戏卡数量 from inserted   --入库后的数量对了,我补充一下,游戏卡出库并不需要在T_Cards表中将游戏卡记录删除,而是将其中一个字段(Owner)的值改变一下就可以了。出库和入库都使用同一个触发器吗?谢谢
      

  4.   

    我详细说一下表的结构
    T_Cards:
    字段名:CardName    CardNumber    PassWord     Owner     ComeFrom
    说明: 游戏卡名称  卡号          密码         拥有人    卡的来源T_Record
    字段名:CardName    BeforeChange  Amount      AfterChange
    说明:  游戏卡名称  出/入库前数量 出/入库数量 出/入库后数量其中ComeFrom表示是谁入库的卡,如果是系统,ComeFrom为"system",如果是经销商则为经销商的账号,现在我只需记录系统的出入库记录(也就是说ComeFrom字段的值一但写入就不会更改),比如说系统入库一张新卡,则在T_Cards中增加一条记录(这时Owner为"system",ComeFrom为"system"),而这时有经销商p1从系统买了一张卡,那这时T_Cards表中所以应的刚刚买的这张卡的Owner字段值就会改为"p1",而ComeFrom的值不会变。
      

  5.   


    T_Record
    字段名:CardName    BeforeChange  Amount      AfterChange
    说明:  游戏卡名称  出/入库前数量 出/入库数量 出/入库后数量
    数量从那里来?? 根据什么判断出库/入库?
      

  6.   

    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:然后再将你更新后的新记录插入到数据表中
    而触发器恰恰显示的证明了这一点.
      

  7.   

    '出库和入库都使用同一个触发器吗?谢谢'
    答;当然可以.
    对了你的T_Record表是不是设个时间字段更好啊.
      

  8.   

    字段名:CardName    BeforeChange  Amount      AfterChange
    说明:  游戏卡名称  出/入库前数量 出/入库数量 出/入库后数量
    --你用前后的数量来比较是是出还是入库?入库的时候,只插入"游戏卡名称 出/入库数量"
    两个字段,你怎么判定他是出还是入?还有,你这样的话,没有唯一的标识(游戏卡名称相同的可以
    有几个吧?),很难得到”出/入库前数量“字段值,建议增加一时间字段,
    --如果你直接插入上面的所有字段,问题你又怎么知道“出/入库前数量”字段值?--建议表结构
    字段名:CardName    BeforeChange optiontype Amount      AfterChange  ChangeDate
    说明:  游戏卡名称  前数量       操作类型    操作数量      后数量      更改时间--用时间段来唯一标识,操作类型来决定是出还是入,这样就可以得到操作前的数量和操作后的数量,
    出入库只需要输入游戏卡名称和操作数量就行了
      

  9.   

    针对出库与入库:select @d=@c-@b --将A类卡入库的数量赋到@d变量中:
    如果是出库的话@d将会是负数,那么就用
    select @d=ABS(@c-@b)解决此问题.建议在T_Record中增加时间与标志字段.标志字段用来判断是出库还是入库.
      

  10.   

    --补充上面:还要加一个操作类型
    --用我的表结构来做个实验给你参考一下吧:
    --建表
    create table T_Record(cardname varchar(10),Beforechange int,optiontype varchar(10),Amount int,AfterChange int,changedate datetime)--插入数据:建议为changedate设置一个默认值,也就是当前的时间,在插入数据的时候,就不用手
    --工插入了
    insert into T_Record select 'A',10,'入库',5,15,'2004-09-21'--构建一个触发器
    alter trigger tri_Record
    on T_Record
    after insert 
    as
    declare 
    @cardname varchar(10),
    @Beforechange int,
    @optiontype varchar(10),
    @Amount int,
    @AfterChange int,
    @changedate datetime
    begin--------------------------------------取得插入的卡号,操作类型,操作数量,和操作时间
    select @cardname=cardname,@optiontype=optiontype,@Amount=Amount,@changedate=changedate
           from inserted
    if (select count(*) from T_Record where cardname=@cardname)>1 --考虑表中是否有记录存在
    begin
    ---------------------------------取得对应卡名的最后一次更新的后数量,
    select @beforechange=AfterChange from T_Record 
    where cardname=@cardname and changedate in 
    (select Max(changedate) from T_Record where changedate<@changedate)
    --------------判断存入还是取出的计算方法,得到操作后的数量
    if(@optiontype='入库')
    begin
    set @AfterChange=@Beforechange+@Amount
    end
    else if(@optiontype='出库')
    begin
    set @AfterChange=@Beforechange-@Amount
    end
    --------------------更新插入记录后的表
    update T_Record set Beforechange=@Beforechange,Afterchange=@Afterchange 
    where changedate=@changedate
    endend--测试:出库实验
    insert into T_Record (cardname,Amount,optiontype,changedate)values('A',5,'出库',getdate())
    --测试:入库
    insert into T_Record (cardname,Amount,optiontype,changedate)values('A',5,'入库',getdate())--结果:
    A        10 入库 5 15 2004-09-21 00:00:00.000
    A        15 出库 5 10 2004-10-02 14:27:13.730
    A        10 入库 5 15 2004
      

  11.   

    我还补充一下,并没有一个字段记录一种卡的数量,所以出/入库前和出/入库后的数量需要统计,也不能用T_Record中的数量做为基数,这样就不能反应出真实的出/入库记录了,比如说我现在需要得到系统的A类卡的库存,就需要从T_Cards表中统计,条件符合CardName='A' and Owner='system' and ComeFrom='system',所以General521(dhy)兄给出的触发器中的@b(出/入库前的数量)和@c(出/入库后的数量)都需要如此统计得来,相反@d(出/入库的数量)是已知的,@d不能由@b-@c,这样也不能反应出真实的情况(如在出入库时出现错误,没有出/入库预期的数量),在记录中给出出/入库标志是可取的,但不是必要的,因为可以从数字中反应出来,谢谢大家的参与,因为下午有点事出去了所以没来及时回复,请大家原谅,并请大家继续帮忙想想,在下不甚感谢。
      

  12.   

    触发器应该在往T_Cards中增加游戏卡或T_Cards表中Owner字段的值改变后工作。但是这样有个问题,如此我一次增加N张到T_Cards,T_Record表中会不会有N条入库数量为1的记录?出库也是一样,能不能只有一条入库数量为N的记录?
      

  13.   

    我把操作过程写明白一点,假设T_Cards和T_Record都为空;操作一:往T_Cards中增加4个名称为A的游戏卡,这时T_Cards表中的内容如下:
    游戏卡名称  卡号          密码         拥有人    卡的来源
      A         c0001         p0001         system    system
      A         c0002         p0002         system    system
      A         c0003         p0003         system    system
      A         c0004         p0004         system    system
    而T_Record表中的内容如下:
    游戏卡名称    出/入库前数量    出/入库数量    出/入库后数量
      A                  0              4             4
    操作一完成。操作二:有经销商P1从系统购了卡A 2张,这时T_Card表中的内容如下:
    游戏卡名称  卡号          密码         拥有人    卡的来源
      A         c0001         p0001         P1        system
      A         c0002         p0002         system    system
      A         c0003         p0003         P1        system
      A         c0004         p0004         system    system
    而T_Record表中的内容如下:
    游戏卡名称    出/入库前数量    出/入库数量    出/入库后数量
      A                  0              4             4
      A                  4              -2            2
    操作2完成这就是我想要的结果
      

  14.   

    请看http://community.csdn.net/Expert/topic/3423/3423661.xml?temp=.5777399
      

  15.   

    --增加一个标识列
    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