例:
INSERT INTO B SELECT ‘0001’,‘1999’,50
当A中有编号为‘0001’,‘1996’时
update a set sl=sl+xxx where bh=xx and ph=xx
当A中没有此编号或是引批号时则:
INSERT INTO A SELECT @BH,@PH,@SL

解决方案 »

  1.   

    这个问题其实很好解决,不过你描述的问题少了一些东西,当修改、删除B表的时候,A表也一样要做修改,以下触发器一并解决这些问题。create trigger tri_b
    on b 
    for insert,update,delete
    asdeclare @Temp table (
    bh  char(4) not null,
    ph  char(6) not null,
    sl numeric(8,2) default(0)
    )declare @TempSum table (
    bh  char(4) not null,
    ph  char(6) not null,
    sl numeric(8,2) default(0)
    )insert @Temp
    select bh,ph,jhsl
    from inserted
    union all
    select bh,ph,-jhsl
    from deletedinsert @TempSum
    select bh,ph,sum(sl)
    from @Temp
    group by bh,phupdate a
    set sl=a.sl+t.sl
    from a,@TempSum t
    where a.bh=t.bh
     and a.ph=t.ph
    insert a(bh,ph,sl)
    select bh,ph,sl
    from @TempSum t
    where not exists (
    select 1 from a
    where bh=t.bh
     and ph=t.ph
    )go
      

  2.   

    这个问题按你的方法是可以解决,
    但对以下两方面是不是有更好的方法:
    一、当多用户工作时,就是多个用户同时INSERT INTO B时,,
    二、当A表有大量数据时,如一百万行或更多时,
    insert a(bh,ph,sl)
    select bh,ph,sl
    from @TempSum t
    where not exists (
    select 1 from a   /*是SELECT * FROM A 吧,,*/
    where bh=t.bh
     and ph=t.ph
    这会不会是一个很耗时的操作,因为要遍历A表!
      

  3.   

    一、这个触发器对多用户一样没有问题,表变量在不同用户不会冲突,而且这个触发器基本上和我自己在用的一样,已经经过我自己实验的了,至少几十个专业操作员同时输入没有问题(还要看网络情况)。
    二、这个问题不用担心,在not exists 的SELECT 里,其实写什么的效率都是一样的!我习惯写个 1,这里写 SELECT 1 、SELECT * SELECT BH都是一样的。
      

  4.   

    想必单条的插入的trigger的sql语句应该没有问题.但是若是以集方式插入,就需要你使用游标.因为可能trigger只会触发一次.
      

  5.   

    CREATE TRIGGER tr_insertB ON B
    FOR INSERT
    AS 
    DECLARE @val1 varchar(30),@val2 varchar(30),@val3 numeric(8,2) 
    DECLARE cufeB CURSOR FOR SELECT bh,ph,jhsl from insertedopen cufeB
    FETCH NEXT FROM cufeb INTO @val1,@val2,@val3WHILE @@FETCH_STATUS = 0
      BEGIN
        IF EXISTS (SELECT * FROM a WHERE bh = @val1 AND ph = @val2 ) THEN
          UPDATE a SET sl = @val3 WHERE bh = @val1 AND ph = @val2
        ELSE
          INSERT INTO a SELECT @val1,@val2,@val3    FETCH NEXT FROM cufeb INTO @val1,@val2  
      ENDCLOSE cufeB
    DEALLOCATE cufeB
      

  6.   

    都要遍历一次A表,看来还是
    : Yang_(扬帆破浪) 的好,,
      

  7.   

    CREATE TRIGGER tr_ins ON dbo.B
    FOR inserted
    AS
    declare @BH  CHAR(4)
    declare @ph char(6)
    declare @sl  numeric(8,2)
    declare @jhsl  numeric(8,2)
    declare @count intbegin tran
    select @bh = bh ,@ph = ph ,@jhsl = jhsl from insertedselect @count = count(*) from A
    where bh = @bh and ph = @phif @count = 0 
      insert into A
      select @bh,@ph,@jhsl
    else
      begin 
      select @sl = sl from A  where bh = @bh and ph = @ph
      update A
      set @sl = @jhsl + @sl
      where  where bh = @bh and ph = @ph
    endcommit tran试试看吧
      

  8.   

    Yang_(扬帆破浪) 我认为你的考虑过于谨慎了,一般来说,出库入库是一个经常性的动作,即使某次操作使某种货物库存为零,但不排除还要进该种货物的可能,所以删除品种 应该不用在这里进行吧  嘻嘻
      

  9.   

    为了程序的可移植,少用trigger...
      

  10.   

    同意楼上的。
    如果是数据量很大的工作表,一是数据的移植,有trigger
    做起来很麻烦。二是要保证数据的一致性,trigger吗?实在
    不敢相信,还是用同一个事务来处理更安全有效。
    至于trigger,用来控制简单的数据操作判断还是可以的。
      

  11.   

    各有各理解,trigger用不好确实祸害很大,因为trigger对数据的修改不是能立刻发现的,移植的考虑也是需要的,但是事务性、安全性的担心就多余了,trigger本身和触发它的语句是在同一个事务里的,如果触发器出错也会回滚触发它的语句。
      

  12.   

    实际上你的问题是如何处理多记录。下面我提供一种解决方案,无需游标,不用区分0条记录/1条记录/多条记录。
    create trigger ti_b on b 
    for insert as
    update a
       set sl = isnull(sl,0) + t1.jhsl
      from inserted t1,a
     where t1.bh = a.bh and
           t1.ph = a.ph
    insert into a(bh,ph,sl)
    select bh,ph,jhsl
      from inserted
     where bh not in (select bh from a) or
           ph not in (select ph from b)
      

  13.   

    不好意思写错一个字.
    create trigger ti_b on b 
    for insert as
    update a
       set sl = isnull(sl,0) + t1.jhsl
      from inserted t1,a
     where t1.bh = a.bh and
           t1.ph = a.ph
    insert into a(bh,ph,sl)
    select bh,ph,jhsl
      from inserted
     where bh not in (select bh from a) or
           ph not in (select ph from a)
      

  14.   

    pbdesigner(MIS/ERP开发) :
    这句话:
      update a
       set sl = isnull(sl,0) + t1.jhsl
      from inserted t1,a
     where t1.bh = a.bh and
           t1.ph = a.ph
    如果bh和ph以前在 a 中不存在,会不会出现置null值的现象, 据我所知,isnull()只能管到有记录但本字段为空的情况,
      

  15.   

    批插入的情况下,trigger确实只会触发一次,但扬帆的做法正是适应这个要求的.唯一的是扬帆的做法不一定令AB表中编号批号完全同步,a表有时会比B表编号多.当然,这个可能不成问题.效率上单条插入扬帆和小亚的差不多,小亚的方法应该不适应批插(只会触发一次).感觉扬帆的还算最佳方法.
      

  16.   

    有索引,并且查询条件与索引有关的情况下,不见得用not exist就非得遍历a表
      

  17.   

    yamato_fg(葡萄)提供的方法是可行的,但用游标处理大量记录时执行效率是个问题。fur16(小亚)的方法没有考虑到多记录,不全面。我提供的方法可以处理任何条记录,执行效率高,特别是对于海量数据。
    “如果bh和ph以前在 a 中不存在,会不会出现置null值的现象”:不存在,如何会出现在更新列表中呢?对谁置空?isnull()正是对出现数据为空时的处理,保险点,实际上如果有缺省值时可省略。