触发器设计

/  触发器添加到多个表
CREATE   TRIGGER   [ TRIGGER_insert ]   ON   [ dbo ] . [ company ]  
FOR   INSERT
AS
insert  Company_Del
select   top   1   *   from  company  order   by  id  desc
/  触发器删除多个表
CREATE   TRIGGER   [ TRIGGER_Del ]   ON   [ dbo ] . [ Dv_User ]  
FOR   delete
AS
    
Delete  Dv_Boke_User 
    
From  Dv_Boke_User br , Deleted  d
    
Where  br.UserName = d.UserName

/  触发器修改多个表
CREATE   TRIGGER   [ TRIGGER_Update ]   ON   [ dbo ] . [ Dv_User ]  
FOR   UPDATE
AS
    
if   Update (UserName)
    
begin

    
Update  br 
      
Set  br.UserName = i.UserName
      
From  Dv_Boke_User br , Deleted d ,Inserted i 
      
Where  br.UserName = d.UserName

    
end
常见的触发器有三种:分别应用于Insert , Update , Delete 事件。

比如图书借阅系统中,有学生数据表和借阅记录表。借阅表以学生编号相关连。
我希望通过触发器达到以下功能:
1、修改学生编号时,与之关联的借阅记录可以同步更新学生编号
2、删除学生记录的同时,与之关联的借阅记录可以自动删除。

实现功能1:
    Create Trigger truStudent         '' 创建一个触发器
      On Student                                 '' 对于学生表
      for Update                                   '' 数据更新事件 字串3
    As
      if Update(StudentID)                 '' 更新学生ID时
      begin                                            '' 开始触发内容

        Update BorrowRecord            '' 更新借阅记录表
          Set StudentID=i.StudentID
          From BorrowRecord br , Deleted  d ,Inserted i 
          Where br.StudentID=d.StudentID 字串3

      end  

实现功能2:
    Create trigger trdStudent
      On Student
      for Delete
    As
      Delete BorrowRecord 
        From BorrowRecord br , Delted d
        Where br.StudentID=d.StudentID

触发器编写问题收集整理

问题一。

有A表  
    字段:a     ,b     ,c  
   B表  
   字段:   d     ,e     ,f  
   C表  
   字段:   g     ,h  
   当A表添加一条记录后,如果新记录中的a字段值在C表中的g字段有相同的值,就把C表中的h字段和新添加的记录b,c 添加到B表中的d,e,f中。如果新记录中的a字段值在C表中的g字段没有相同的值就不执行。  
   
    怎么能够实现啊??各位达人帮帮忙!谢谢 

解决办法:

CREATE   TRIGGER   A_Insert    
  ON   A  
  FOR   INSERT  
  AS  
        insert   into   B(d,e,f)    
        select   C.h   ,   D.b   ,   D.c    
        from       C   ,   inserted   D  
        where     C.g   =   D.a  
  GO

 

问题二.

我有一个表test,主键是个流水号test_id,现在要在程序里插入一行,怎么自动生成这个id?  
  请高手指教?

解决办法:

第一步:创建SEQUENCE  
  create   sequence   s_country_id   increment   by   1   start   with   1   maxvalue   999999999;  
  第二步:创建一个基于该表的before   insert   触发器,在触发器中使用该SEQUENCE  
  create   or   replace   trigger   bef_ins_t_country_define  
  before   insert   on   t_country_define  
  referencing   old   as   old   new   as   new   for   each   row  
  begin  
  new.country_id=s_country_id.nextval;  
  end;

 

问题三.

比方说有两张表,Dept和Class.Class中有个外键Dept_id在Dept表中。删除Dept中某条记录即将Class中相应记录删除。应该是比较简单的,请高手指点。

解决办法:

cteate   trigger   tr_dept_delete  
  on   dept  
  for   delete  
  as  
  delete   class  
  where   dept_id   in   (select   dept_id   from   deleted)  
  go   
 

 

问题四:

如果希望把一个表中删除   添加   修改的记录全部都插入另一个表中,怎么写触发器!  
   
  写小例子~~谢谢

解决办法:

create   table   t  
  (id   int   identity(1,1),col   varchar(20))  
   
  create   table   t1  
  (id   int   identity(1,1),t_id   int,col1   varchar(20))  
  go  
   
  create   trigger   t_i_u_d  
  on   t  
  for   insert,update,delete  
  as  
  set   xact_abort   on  
  begin   tran  
        insert   t1(t_id,col1)  
          select   *   from   inserted  
          union   all  
          select   *   from   deleted  
  commit   tran  
  go  
   
  insert   t   values   ('234')  
   
  insert   t   values   ('345')  
   
  update   t   set   col='567'   where   col='234'  
   
  delete   from   t  
   
  select   *   from   t1  
   
  drop   trigger   t_i_u_d  
   
  drop   table   t1,t  
   
  id                     t_id                 col1                                    
  -----------   -----------   --------------------    
  1                       1                       234  
  2                       2                       345  
  3                       1                       567  
  4                       1                       234  
  5                       1                       567  
  6                       2                       345  
   
  (所影响的行数为   6   行)

 

问题五:

我想在db_user表里插入usernmae,userpassword,useremail的同时,在db_user1里也插入相应的值。  
  现在碰到的问题是,比如我在db_user里三个字段里分别插入'aaaa','bbbbbbbb','ccccc',  
  但是在db_user1表的三个字段却相映为'a','b','c',数据只有一个字符。  
  求教。  
   
  代码如下:  
   
  CREATE   TRIGGER   db_user_insert   ON     db_user    
  FOR   INSERT  
  AS  
   
   
  DECLARE   @username   nvarchar,@userpassword   nvarchar,@useremail   nvarchar  
  SELECT   @username=username,@userpassword=userpassword,@useremail=useremail   FROM   inserted  
  IF   @@rowcount>0  
  BEGIN  
  INSERT   INTO   db_user1(username,userpassword,useremail)  
  VALUES(@username,@userpassword,@useremail)  
  END 

解决办法:

1楼:你的触发器只得到一个字符的原因是nvarchar没有定义长度,系统会默认长度为1。  
   
  另外,不建议写触发器时像你这么写。  
   
  你这么写的话,一次插入多条数据就会出问题。  
 CREATE   TRIGGER   db_user_insert   ON     db_user    
  FOR   INSERT  
  AS  
  INSERT   INTO   db_user1(username,userpassword,useremail)  
  select   username   ,userpassword,useremail   from   inserted  
  GO

 

2楼:

DECLARE   @username   nvarchar,@userpassword   nvarchar,@useremail   nvarchar  
  ===========>  
  DECLARE   @username   nvarchar(20),@userpassword   nvarchar(20),@useremail   nvarchar(20)  
   
  不声明长度的话会截掉的

 

 

问题六:

触发器中:     select   id   from   inserted  
  这个句子有个情况不适合,  
  就是如果一次操作插入的是多行,这条语句不就不行了么,  
  那为什么检查语法时还没错误呢

回答:

CREATE   TRIGGER   TR_ZZ   ON   ZZ  
  FOR   INSERT    
  AS  
  BEGIN  
   
  DECLARE   @ZZLB   VARCHAR(30),  
                  @CSZ   NUMERIC(9,1),  
                  @ZZS   NUMERIC(9,1),  
                  @ZZBH   BIGINT  
   
   
  declare   cur   insensitive   cursor   for  
  select   ZZBH,ZZLB,ZZS   from   inserted   for   read   only  
   
  open   cur  
  fetch   next   from   cur   into   @ZZBH,@ZZLB,@ZZS  
  while(   @@fetch_status   <>   -1   )  
  begin  
  IF   @ZZLB='专著'  
            SET   @CSZ=(SELECT   CSZ   FROM   CSFZ   WHERE   CSDH='61')  
  ELSE  
            SET   @CSZ=(SELECT   CSZ   FROM   CSFZ   WHERE   CSDH='62')  
  UPDATE   ZL    
            SET   ZZFS=@ZZS*@CSZ    
            WHERE   ZL.ZZBH=@ZZBH  
  fetch   next   from   cur   into   @ZZBH,@ZZLB,@ZZS  
  end  
   
  close   cur  
  deallocate   cur  
  END 

要提醒你:  
  SET   @CSZ=(SELECT   CSZ   FROM   CSFZ   WHERE   CSDH='61')好象有误,应该改为:  
  SElect   @CSZ=(SELECT   CSZ   FROM   CSFZ   WHERE   CSDH='61')   或SElect   @CSZ=CSZ   FROM   CSFZ   WHERE   CSDH='61'   这里要注意也必须只能返回一个值。  
  

 

问题七:

例如,假设有一个数据库包含三个表:TableA、TableB   和   TableC。针对   TableA   中的主键,用   ON   DELETE   CASCADE   定义   TableB   中的外键。针对   TableB   中的主键,用   ON   DELETE   CASCADE   定义   TableC   中的外键。如果   DELETE   语句删除   TableA   中的行,则该操作也将删除   TableB   中具有与   TableA   中所删除的主键匹配的任何外键中的所有行,然后删除   TableC   中具有与   TableB   中所删除的主键匹配的任何外键中的所有行。  
   
   
  触发器和级联引用操作  
  级联引用操作按下列顺序激发   AFTER   触发器:    
  1、首先执行由原始   DELETE   或   UPDATE   直接导致的所有级联引用操作。  
  2、当完成原始级联引用操作后,无论是否更新了任何行,都将激发原始表上的   AFTER   触发器。  
  3、然后激发级联引用操作链中表上的   AFTER   触发器,但只有已更新或删除了表中的一行或多行时才激发。    
  如果任何原始级联引用操作集生成任何错误,则产生错误,不激发   AFTER   触发器,并且回滚   DELETE   或   UPDATE。  
   
  这个是SQLSERVER的联机丛书上写的。  
   
  我有疑惑,按上面的说明,是先把3个表中的数据先删除然后在执行每个表中的触发器。但触发器中如果使用到了临时表Deleted,要从Deleted中取数据,那这个表中的数据到底是些什么?因为3个表中的数据都已经删掉了。  
   
  小弟初涉这个,对Deleted和Inserted临时表还不熟悉,希望高人指点迷津。 

 

回答:

二楼:

deleted表对于delete   和   update   操作,inserted   表对于insert   和   update操作,其表的结构跟触发的表结构相同  
   
  对于delete和insert相对比较简单,就是对表上次的delete和insert所影响的数据.分别存放于deleted和inserted表中  
   
  对于update,过程是先delete原数据,之后再insert更新数据.

三楼:

Deleted   表用于存储   DELETE   和   UPDATE   语句所影响的行的复本。在执行   DELETE   或   UPDATE   语句时,行从触发器表中删除,并传输到   deleted   表中。Deleted   表和触发器表通常没有相同的行。  
   
  Inserted   表用于存储   INSERT   和   UPDATE   语句所影响的行的副本。在一个插入或更新事务处理中,新建行被同时添加到   inserted   表和触发器表中。Inserted   表中的行是触发器表中新行的副本。 

四楼:

照这么说那在级联操作中,如题目中的例子,Deleted表中保存的就是对表TableC所影响的数据,  
   
  但现在是先级联操作完再激发每个表上的触发器,TableA、TableB、TableC三个表中的触发器都使用了Deleted,那头2个触发器不都不能正常激发了。

五楼:

当delete   from   tableA   where   ....时,  
    TableA   的deleted   表中存放执行delete   from   tableA   where   ....操作后所删除的数据  
    TableB   的deleted   表中存放级联删除tableB中的数据,如果级联错误,则不会触发  
    TableC   的deleted   表中存放级联删除tableC中的数据,如果级联错误,则不会触发 

六楼:

现在是先级联操作完再激发每个表上的触发器,就是说如果TableA的触发器执行了,就不存在级联错误,那么TableB和TableC的触发器都会触发。  
   
  按照aflyingpig(五楼)的观点,TableA、TableB、TableC三个表删除的数据都存放在Deleted中,是这个意思吗?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值