在写新凭证的时候,会触发UPDATE触发器,但是fvoucherid在数据库里还没有,为什么@Count总是返回1呢?到错误提示出现后,我根据fvoucherid查询数据库,数据是空的,为什么会有记录返回?CREATE TRIGGER t_Voucher_Update ON t_Voucher
FOR  UPDATE
AS
set nocount on declare @Count as int --如果凭证已存在,则不允许修改
declare @VoucherID as int set @Count=(select  count(fvoucherid)  from t_Voucher where fvoucherid=(select fvoucherid from inserted))
set @VoucherID=(select fvoucherid from inserted)
print @Count if @Count<>0 
begin
raiserror('物流账套生成凭证,不允许修改!',16,1,@VoucherID)
end

解决方案 »

  1.   

    ---改成这样试试看
    CREATE TRIGGER t_Voucher_Update ON t_Voucher
    FOR  UPDATE
    AS
        declare @Count as int --如果凭证已存在,则不允许修改 
        declare @VoucherID as int
        select @Count=count(t.fvoucherid) from t_Voucher t,inserted i where t.fvoucherid=i.fvoucherid
        select @VoucherID=fvoucherid from inserted
    print @Count   ---看看@count是... if @Count<>0 
    begin
    raiserror('物流账套生成凭证,不允许修改!',16,1,@VoucherID)
    end
      

  2.   

    你把上面的Inserted 改成Deleted再试看看....
    ...
    select @Count=count(t.fvoucherid) from t_Voucher t,deleted d where t.fvoucherid=d.fvoucherid
    ...
      

  3.   

    CREATE TRIGGER t_Voucher_Update ON t_Voucher
    FOR  UPDATE
    AS
    set nocount on declare  as int
    declare @VoucherID as int select  @Count = count(fvoucherid) 
    from t_Voucher v 
    join inserted i on i.fvoucherid = v.fvoucherid

    select @VoucherID fvoucherid from inserted--这里只能查询出一个重复的fvoucherid
    print @Count if @Count<>0 
    begin
    raiserror('物流账套生成凭证,不允许修改!',16,1,@VoucherID)
    end
      

  4.   

    select @VoucherID fvoucherid from inserted--这里只能查询出一个重复的fvoucherid
    少了等号select @VoucherID =fvoucherid from inserted--这里只能查询出一个重复的fvoucherid
      

  5.   

    指定触发器只有在触发 SQL 语句中指定的所有操作都已成功执行后才激发。所有的引用级联操作和约束检查也必须成功完成后,才能执行此触发器。也就是说,你的触发器是在UPDATE之后才执行,当然返回1。
      

  6.   

    是哦,刚才没仔细看,你写的触发器逻辑有问题,你都能update了,说明记录就存在了嘛.
      

  7.   

    使用包含 COMMIT 或 ROLLBACK TRANSACTION 的触发器
    仅当语句开始时事务计数为 0 时,Microsoft SQL Server 2000 才增加语句内的事务计数。在 SQL Server 版本 7.0 中,无论语句开始时的事务计数为何值,该计数总是增加。这可能导致触发器中的 @@TRANCOUNT 返回的值在 SQL Server 2000 中比在 SQL Server 版本 7.0 中低。在 SQL Server 2000 中,如果在触发器中执行 COMMIT TRANSACTION 或 COMMIT WORK 语句,并且在触发器开始没有显式或隐式 BEGIN TRANSACTION 语句,则对用户显示的行为与 SQL Server 版本 7.0 不同。不建议将 COMMIT TRANSACTION 或 COMMIT WORK 语句置于触发器中。当包含 ROLLBACK TRANSACTION 语句的触发器从批处理中执行时,它们会取消整个批处理。在下面的示例中,如果 INSERT 语句引发了包含 ROLLBACK TRANSACTION 的触发器,则由于批处理被取消,DELETE 语句没有执行:/* Start of Batch */
    INSERT employee VALUES ('XYZ12345M', 'New', 'M', 'Employee', 1, 1, '9952', '6/1/95') -- Causes trigger to fire and ROLLBACK TRANSACTION.
    DELETE employee WHERE emp_id = 'PMA42628M'
    GO如果包含 ROLLBACK TRANSACTION 语句的触发器从用户定义的事务中引发,则 ROLLBACK TRANSACTION 回滚整个事务。在本示例中,如果 INSERT 语句引发了包含 ROLLBACK TRANSACTION 的触发器,UPDATE 语句同样被回滚:/* Start of Transaction */
    BEGIN TRANSACTION
    UPDATE employee SET hire_date = '7/1/94' WHERE emp_id = 'VPA30890F'
    INSERT employee VALUES ('XYZ12345M', 'New', 'M', 'Employee', 1, 1, '9952', '6/1/95') -- Causes trigger to fire and ROLLBACK TRANSACTION
    请参见在存储过程和触发器中回滚ROLLBACK TRANSACTION事务&#169;1988-2004 Microsoft Corporation. 保留所有权利。
      

  8.   

    以上内容来自 SQL 2000 的《联机丛书》:索引 -> 触发器 -> ROLLBACK TRANSACTION应该可以实现你的要求。
      

  9.   

    用 INSTEAD OF 触发器效果更好。
      

  10.   

    mengmou()mengmou() ( ) 信誉:98  2007-08-09 16:45:59  得分: 0  
     
     
       是哦,刚才没仔细看,你写的触发器逻辑有问题,你都能update了,说明记录就存在了嘛.
      
     
      

  11.   

    触发器问题最好说清楚你想要的效果,否则不止到你的判断错在哪里一般校验的触发器如果是for触发器,raiserror了应该ROLLBACK TRANSACTION 也许用能方便的进行你需要的判断,而且不必ROLLBACK TRANSACTION 
      

  12.   

    谢谢各位老大的判断,我又数据库里跟踪了一下,确实是已经有插入的数据存在了.而且写完以后,又触发了UPDATE事件,这里我想判断一下TYPE=1的就不让修改了,但是在插入的时候,他同时触发这个事件,就导致写数据也写不上了,就想实现这个功能,谢谢
      

  13.   

    简单说,确实有点前后矛盾
    我想在UPDATE时,判断一下TYPE=1就执行,但是在插入数据时,这个触发器也同时触发
    但是插入的数据还正在TYPE=1的,有不有什么办法,可以判断一下,是新插入还是修改
      

  14.   

    在写入数据的时候,同时触动发UPDATE,这时在UPDATE里面我加了判断条件,
    select fvoucherid from inserted,因为inserted符合不让修改的条件,所以这时候插入数据就会提示错误
      

  15.   

    这样试试:
    CREATE TRIGGER t_Voucher_Update ON t_Voucher
    FOR  UPDATE
    AS
    set nocount on
    if exists(select 1 from inserted where type = 1)  /*在此判断是否有type = 1的记录*/
    begin
        declare @VoucherID as int
        select @VoucherID = fvoucherid from inserted where type = 1
        raiserror('物流账套已生成凭证%d,不允许修改!',16,1,@VoucherID)
        rollback   /*回滚触发器,使本次修改失败*/
        return     /*出现错误后结束触发器*/
    end
    GO