您的位置:程序门 -> ms-sql server -> 基础类



关于触发器的问题?


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


关于触发器的问题?
发表于:2007-04-06 09:18:18 楼主
小弟我不明白触发器的原理!以及怎么在多个表上建触发器?
      谢谢!请高手予以指教
发表于:2007-04-06 09:20:541楼 得分:0
问的太广了吧,三言两语怎么说清如何使用?

看教程吧
发表于:2007-04-06 09:25:462楼 得分:0
看联机帮助,那上面写的很清楚
发表于:2007-04-06 09:28:483楼 得分:0
看资料吧,你问的太笼统了
就一张表的数据只有insert   update   delete操作
那么应对这3个操作,相当于产生对应数据快照
insert   :inserted
delete   :deleted
update   :inserted、deleted
这些在完成后的事务日志里也可以看到

触发器还分为for(after)和instead   of   2种
其实这个用法很简单,看几个简单的例子,你就明白了
发表于:2007-04-06 09:32:304楼 得分:0
http://blog.sina.com.cn/u/4931fcee0100066o

insert触发器的工作过程  

可以定义一个无论何时用insert语句向表中插入数据时都会执行的触发器。
当触发insert触发器时,新的数据行就会被插入到触发器表和inserted表中。inserted表是一个逻辑表,它包含了已经插入的数据行的一个副本。inserted表包含了insert语句中已记录的插入动作。inserted表还允许引用由初始化insert语句而产生的日志数据。触发器通过检查inserted表来确定是否执行触发器动作或如何执行它。inserted表中的行总是触发器表中一行或多行的副本。
日志记录了所有修改数据的动作(insert、update和delete语句),但在事务日志中的信息是不可读的。然而,inserted表允许你引用由insert语句引起的日志变化,这样就可以将插入数据与发生的变化进行比较,来验证它们或采取进一步的动作。也可以直接引用插入的数据,而不必将它们存储到变量中。  

delete触发器的工作过程  

当触发delete触发器后,从受影响的表中删除的行将被放置到一个特殊的deleted表中。deleted表是一个逻辑表,它保留已被删除数据行的一个副本。deleted表还允许引用由初始化delete语句产生的日志数据。
使用delete触发器时,需要考虑以下的事项和原则:
  当某行被添加到deleted表中时,它就不再存在于数据库表中;因此,deleted表和数据库表没有相同的行。
  创建deleted表时,空间是从内存中分配的。deleted表总是被存储在高速缓存中。
  为delete动作定义的触发器并不执行truncate   table语句,原因在于日志不记录truncate   table语句。  

update触发器的工作过程  

可将update语句看成两步操作:即捕获数据前像(before   image)的delete语句,和捕获数据后像(after   image)的insert语句。当在定义有触发器的表上执行update语句时,原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。
触发器检查deleted表和inserted表以及被更新的表,来确定是否更新了多行以及如何执行触发器动作。
可以使用if   update语句定义一个监视指定列的数据更新的触发器。这样,就可以让触发器容易的隔离出特定列的活动。当它检测到指定列已经更新时,触发器就会进一步执行适当的动作,例如发出错误信息指出该列不能更新,或者根据新的更新的列值执行一系列的动作语句。
发表于:2007-04-06 09:44:555楼 得分:0
联机帮助是个好东东
发表于:2007-04-06 11:25:526楼 得分:0
首先建议lz好好去读读online   book。
下面我从总体上总结一下有关触发器方面的知识:
(1)和触发器紧密相关的两个表:inserted表和deleted表
sql   server为每个触发器都创建了两个专用表:inserted表和deleted表。这是两个逻辑表,由系统来维护,用户不能对它们进行修改。它们存放在内存而不是数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行完成后,与该触发器相关的这两个表也会被删除。
(2)触发器的两种类型:instead   of和after触发器
这两种触发器的差别在于它们被激活的时机不同:
1.instead   of触发器用于替代引起触发器执行的t-sql语句。可用于表和视图。
2.after触发器在一个insert、update或delete语句之后运行,进行约束检查等动作都将在after触发器被激活之前发生。只可用于表。
(3)创建触发器
一个表上可以有多个具有不同名称的、各种类型的触发器,且每个触发器都可以完成不同的功能,但每个触发器只能作用在一个表上。
发表于:2007-04-06 11:45:167楼 得分:0
大侠!能不能用两个示例详细说明一下以下两种方式:
小弟不盛感激!!!!!
1.instead     of触发器用于替代引起触发器执行的t-sql语句。可用于表和视图。    
2.after触发器在一个insert、update或delete语句之后运行,进行约束检查等动作都将在after触发器被激活之前发生。只可用于表。    
发表于:2007-04-06 11:56:228楼 得分:0
楼主看一下联机帮助里很详细了
发表于:2007-04-06 13:20:569楼 得分:0
散分吗?我接
发表于:2007-04-06 13:39:2310楼 得分:0
print   'the   after----------------------------------------------- '
go
create   table     taa(id   int,name   varchar(20)   default   '0 ')--改一下
go
create   trigger   dddd
on   taa
for   insert
as
    declare   @a   varchar(20)
    declare   @id   int
    select   @id   =   id,@a   =   name   from   inserted
    if   @a   =   ' '   update   taa   set   name   =   '0 '   where   id   =   @id
go

insert   into   taa   (id,name)values(1, ' ')
select   *   from   taa

drop   trigger   dddd
go


--create   table     taa(id   int,name   varchar(20)   default   '0 ')--改一下
--go

print   'the   instead   of   ----------------------------------------------- '
go
create   trigger   dddd
on   taa
instead   of   insert
as
    declare   @a   varchar(20)
    declare   @id   int
    select   @id   =   id,@a   =   name   from   inserted
    if   @a   =   ' '  
insert   into   taa(id)   values(@id)
    else
                insert   into   taa(id,name)   values(@id,@a)  
go

insert   into   taa   (id,name)values(1, ' ')

select   *   from   taa


drop   table   taa


/*

the   after-----------------------------------------------

(所影响的行数为   1   行)


(所影响的行数为   1   行)

id                     name                                  
-----------   --------------------  
1                       0

(所影响的行数为   1   行)

the   instead   of   -----------------------------------------------

(所影响的行数为   1   行)


(所影响的行数为   1   行)

id                     name                                  
-----------   --------------------  
1                       0
1                       0

(所影响的行数为   2   行)


*/
发表于:2007-04-06 13:40:2411楼 得分:0
大侠!能不能用两个示例详细说明一下以下两种方式:
小弟不盛感激!!!!!
1.instead     of触发器用于替代引起触发器执行的t-sql语句。可用于表和视图。    
2.after触发器在一个insert、update或delete语句之后运行,进行约束检查等动作都将在after触发器被激活之前发生。只可用于表。  
---------------------------------------------------

好的。
(1)instead     of触发器实例
在视图上可以创建instead   of触发器,而且如果定义视图的查询语句中有要导出的列,只能通过instead   of触发器对其进行更新,本例就将介绍instead   of触发器是如何更新有导出列的视图的。  
以customers表为基表创建一个视图simplecustomers,该视图包含客户的简单信息,比如客户姓名、城市、电话。其中,客户姓名是由customers表中的客户姓(lastname)和名(firstname)列连接得到的列。
创建simplecustomers视图的代码如下:
create   view   simplecustomers
(customername,city,tel)
as
select   firstname+ ', '+lastname,city,tel
from   customers
为了能通过simplecustomers视图向customers表添加记录,可以定义如下的触发器:
create   trigger   insertcustomer   on   simplecustomers
instead   of   insert
as
declare   @name   varchar(40)
declare   @firstname   varchar(20)
declare   @lastname   varchar(20)
declare   @city   varchar(20)
declare   @tel   varchar(20)
declare   @idx   int
select   @name   =   customername,@city   =   city,@tel   =   tel   from   inserted
set   @idx   =   charindex( ', ',@name)
set   @firstname   =   left(@name,@idx-1)
set   @lastname   =   right(@name,len(@name)-@idx)
insert   into   customers(firstname,lastname,city,tel)
values(@firstname,@lastname,@city,@tel)
说明:当向simplecustomers视图执行insert语句时,insertcustomer触发器被触发,这时inserted表中已经有了要插入的数据,在insertcustomer触发器的代码中,分析插入的客户姓名字符串,将其分拆为姓和名两个字符串,并插入基表customers,而原来的insert语句不会被执行。
(2)after触发器实例
在orders表上建立一个插入触发器,在添加一个订单时,减少goods表相应货品记录中的库存量。
create   trigger   orderinsert2   on   orders
for   insert
as
update   goods   set   storage   =   storage   -   inserted.quantity
from   goods,inserted
where   goods.name   =   inserted.goodsname
发表于:2007-04-06 13:54:5012楼 得分:0
做两个例子就熟悉了  
楼主
发表于:2007-04-06 13:58:1213楼 得分:0
use   pubs
go
begin   tran
create   table   table1(列1   int,列2   int)
create   table   table2(列11   int,列22   int)
go

create   trigger   t_dalii   on   table1
after   insert
----^^^^^^当插入时触发
as
begin
    select   *   from   table2;
    insert   table2   select   *   from   inserted
-------------------------------^^^^^^^^^存放插入临时数据的临时表
end
go

----------**你向table1插入数据时table2也会插入同样的数据**--
insert   table1   values(1,2)
select   *   from   table1
select   *   from   table2
drop   table   table1
drop   table   table2
commit   tran

http://blog.csdn.net/put2006/archive/2005/10/12/500401.aspx
这儿详细一点
发表于:2007-04-06 14:00:1014楼 得分:0
在表中建立触发器﹐当向orders表中插入一条订单记录时﹐检查goods表的货品状态status是否为1(正在整理)﹐是﹐则不能往orders表加入该订单。
create   trigger   orderinsert
on   orders
after   insert
as  
if   (select   status   from   goods,inserted
where   goods.name=inserted.goodsname)=1
begin
print   'the   goods   is   being   processed '
print   'the   order   cannot   be   committed '
rollback   transaction       --回滚﹐避免加入
end


快速检索

最新资讯
热门点击