回答1:因为表中已有ID为主键,NOT NULL。所以在执行INSERT时,它会检查ID是否为空。因此会出现错误。触发器是在INSERT执行后,但还没提交(COMMIT)时发生的。可以通过在ID中写入一个整数,但不会在表中出现的值,比如-1。
我认为可这样写:
create trigger autoincreate on frienslist
for insert
as
  declare @row int,@id int
  select @row=@@rowcount
  if @row>1 
  begin
   print 'can't insert more than one row'
   rollback tran
  end 
  update friendslist set id=id where 1=2/*锁定这个表*/
  select @id=max(id)+1 from friendslist
  update friendslist set id=@id from friendslist,inserted where friendslist.id=inserted.id
go

解决方案 »

  1.   

    忘了一个ELSE,补上。
    create trigger autoincreate on frienslist
    for insert
    as
      declare @row int,@id int
      select @row=@@rowcount
      if @row>1 
      begin
      print 'can't insert more than one row'
      rollback tran
      end 
      else
      begin
      update friendslist set id=id where 1=2/*锁定这个表*/
      select @id=max(id)+1 from friendslist
      update friendslist set id=@id from friendslist,inserted where friendslist.id=inserted.id
       end
    go
      

  2.   

    929兄,INSERTED是什么?啃SQL SERVER ONLINE BOOK真的很辛苦,全E文啊...:(
    还有,请仔细解释一下这句怎么锁定表:
    update friendslist set id=id where 1=2/*锁定这个表*/辛苦了。
      

  3.   

    自动递增的ID: UNIQUE IDENTITY
      

  4.   

    INSERTED表是INSERT触发器执行时由SERVER产生的一个局部表,它是在进行INSERT时向表中新插入的数据,表结构与原表一样。
    在SQL SERVER中执行UPDATE操作,如果不COMMIT,将会在表上维持独占锁。这时,其它事务会话无法访问这个表,因此锁表。实际上在INSERT触发器中,它们实际是在一个事务中,还没COMMIT,表已经锁住了。这句可有可无。
    用update friendslist set id=id where 1=2/*锁定这个表*/,这句即发出了UPDATE语句请求一个独占锁,又因为条件1=2始终为假,所以SERVER可以马上判断不必进行实际硬盘的操作,但锁已经有了。
    与INSERTED类似,在DELETE触发器中有DELETED表,代表在DELETE语句中所删除的记录。而在UPDATE触发器中同时有INSERTED,DELETED表。分别代表更新前的数据(DELETED)和更新后的数据(INSERTED)。
      

  5.   

    我真的不明白,sql server提供的set identity on怎么就不用呢?
      

  6.   

    至haihong:
        因为我想学写触发器:)
      

  7.   

    对不起king兄,借你地盘用.请929大侠看一看看http://expert.csdn.net/TopicView.asp?id=12135