我是靠谱客的博主 平常柚子,最近开发中收集的这篇文章主要介绍SQL_Server_2008完全学习之第十章触发器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

-

1、什么时触发器?

 

1)触发器是一个在修改指定表中的数据时执行的存储过程。经常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性或一致性。由于用户不能绕过触发器,所以可以用它来强制实施复杂的业务规则,以此确保数据的完整性。

2)触发器不同于存储过程。触发器主要是通过事件进行触发而被执行的,而存储过程可以通过存储过程名字而被直接调用。当对某一表进行诸如:UDPATE、INSERT、DELETE这些操作时,SQL Server就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合由这些SQL语句所定义的规则。

 

为什么要使用触发器?

1)触发器自动执行,它们在表的数据作了任何修改(比如手工输入或者使用程序采集的操作)之后立即激活。

2)触发器可以通过数据库中的相关表进行层叠更改。这比直接把代码写在前台的做法更完全合理。

3)触发器可以强制限制,这些限制比用CHECK约束所定义的更复杂。与CHECK约束不同的是,触发器可以引用其他表中的列。

 

触发器的种类

 

1)DDL触发器

DDL触发器当服务器或者数据库中发生数据定义语言(DDL)事件时被调用。如果要执行以下操作,可以使用DDL触发器:

a)要防止对数据库架构进行某些更改

b)希望数据库中发生某种情总以响应数据库架构中的更改

c)要记录数据库架构中的更改或者事件

2)DML触发器

DML触发器是当数据库服务器发生数据操作语言(DML)事件时要执行的操作。通常所说的DML触发器主要包括三种:INSERT触发器、UPDATE触发器、DELETE触发器。DML触发器可以查询其他表,还可以包含复杂的T-SQL语句。将触发器和触发它的语句做为可在触发器内回滚的单个事务对待。如果检测到错误,则整个事务自动回滚。

 

2、创建INSERT触发器

 

语法格式

CREATE TRIGGER trigger_name

ON {table|view}

{

{{FOR | AFTER | INSTEAD OF}

{[DELETE][,][INSERT][,][UPDATE]}

AS

sql _statement

}

}

 

-- 创建订单时,减少相应产品的库存数量
CREATE  TRIGGER t_AddOrder
on  [ ORDER ]
for  insert
as 
declare  @pid  int@sale  int
select  @pid =pid, @sale = [ count ]  from inserted
update product  set proCount =proCount - @sale  where PID  =  @pid

 

3、创建DELETE触发器

 

-- 删除订单时,减少相应产品的库存数量
ALTER  TRIGGER t_RemoveOrder
on  [ ORDER ]
for  delete
as 
DECLARE cur_deleted scroll  CURSOR 
FOR  select pid, [ count ]  from deleted
FOR  read  only
OPEN cur_deleted
declare  @pid  int@sale  int
FETCH  NEXT  FROM cur_deleted  into  @pid, @sale
while  @@fetch_status = 0
BEGIN
     update product  set proCount =proCount + @sale  where PID  =  @pid
     FETCH  NEXT  FROM cur_deleted  into  @pid, @sale
End

CLOSE cur_deleted
DEALLOCATE cur_deleted

insert  into  [ Order ] (pid, [ count ]values ( 1, 2)
insert  into  [ Order ] (pid, [ count ]values ( 2, 3)

delete  [ Order ]

select  *  from  [ Order ]
select  *  from  [ Product ]

 

4、创建UPDATE触发器

 

注:可以把UPDATE动作看作DELETE + INSERT 动作的组合,既先删除旧的这些记录,再插入一条新的记录,此时在数据库中存在了两个临时表,既是DELETED和INSERTD。

 

-- 使用UPDATE触发器给列加上修改权限

CREATE  TRIGGER t_EditProduct
ON  [ Product ]  For  Update
as
if  update(proName)
BEGIN
     print  ' 产品名称为基础数据,不能被修改! '
     -- 回滚事务
     ROLLBACK  Transaction
END
else
BEGIN
     print  ' 修改成功! ';
END

-- 执行失败
UPDATE Product  set proName = ' IPhone 4 '  where pid  =  1
-- 执行成功
UPDATE Product  set proCount = 10  where pid  =  1

 

5、创建DDL触发器

 

语法格式

CREATE TRIGGER trigger_name

ON {ALL SERVER|DATABASE}

WITH ENCRYPTIION

FOR|AFTER|{event_type}

AS

sql_statement

 

-- 使用DDL触发器禁止删除或修改表
CREATE  trigger t_DontDeleteTables
ON  Database
For Drop_table,Alter_table
AS
Begin
     print  ' 系统禁止删除或修改表! ';
     Rollback  Transaction
End

DROP  table  [ Order ]

 

6、管理触发器

 

-- 删除触发器
drop  trigger trigger_name

-- 禁用触发器
disable  trigger trigger_name

-- 启用触发器
enable  trigger trigger_name

-- 示例
ALTER  table  [ Order ]  add status  int  not  null  default  0
-- 禁用指定触发器
disable  trigger t_DontDeleteTables

 

7、嵌套触发器(最多32层)

 

 

-- 嵌套触发器完整示例
CREATE  TABLE Department(
departmentId  int  not  null  identity( 1, 1primary  key,
departmentName  nvarchar( 20not  null,
departmentCount  int  not  null  default  0
)

CREATE  TABLE Personnel(
personnelId  int  not  null  identity( 1, 1primary  key,
departmentId  int  not  null,
personnelName  nvarchar( 10not  null
)

CREATE  TABLE NewPersonnel
(
personnelId  int  not  null  identity( 1, 1primary  key,
departmentId  int  not  null,
personnelName  nvarchar( 10not  null
)

insert  into Department (departmentName)  values ( ' 总经办 '),( ' 财务部 '),( ' 行政人事部 '),( ' 信息技术部 '),( ' 市场研发部 '),( ' 售后客服部 ')

CREATE  TRIGGER t_Delete 
ON NewPersonnel
FOR  DELETE
as
BEGIN
     insert  into Personnel  select departmentId,personnelName  from deleted
END

CREATE  TRIGGER t_Insert
ON Personnel
FOR  INSERT
as
BEGIN
     declare  @departmentId  int
     select  @departmentId  = departmentId  from insertd
     update department  set departmentCount =( select  count( 1from Personnel  where departmentId = @departmentIdwhere departmentId = @departmentId
END

select  *  from department

insert  into NewPersonnel(departmentId,personnelName)  values ( 1, ' 王** '),( 1, ' 毛* '),( 1, ' 张** ')
insert  into NewPersonnel(departmentId,personnelName)  values ( 2, ' 宋** '),( 2, ' 高** '),( 2, ' 殷** ')
insert  into NewPersonnel(departmentId,personnelName)  values ( 3, ' 庄** '),( 3, ' 施** '),( 3, ' 胡* '),( 3, ' 刘** ')
insert  into NewPersonnel(departmentId,personnelName)  values ( 4, ' 张* '),( 4, ' 宋** '),( 4, ' 陈** ')

DELETE  [ NewPersonnel ]  where departmentId  =  4

 

8、递归触发器

 

任何触发器都可以包含影响同一个表或另一个表的UPDATE/INSERT或DELETE语句。如果启用递归触发器选项,那么改变表中数据的触发器,通过递归执行就可以再次触发自己。在数据库创建时,默认情况下递归触发器选项是禁用的,但可以使用ALTER DATABASE语句来启用它。

 

递归触发器具有复杂特性,可以用它来解决诸如自引用关系这样的复杂关系。使用递归触发器时,需要考虑以下的事项和原则:

1)递归触发器很复杂,必须经过有条理的设计和全面的测试。

2)在任意点的数据修改会触发一系列触发器。尽管提供处理复杂关系的能力,但是如果表要求以特定的顺序更新用户的表时,使用递归触发器就会产生问题

3)所有触发器一起构成一个大事务。任何触发器中的任何位置上的ROLLBACK命令都将取消所有数据输入。所有数据均为擦除,并且无任何数据被放到表中

4)触发器最多只能递归16层。换句话说,如果递归链中的第16个触发器激活了第17个触发器,则结果与发布ROLLBACK命令一样,所有数据将被擦除。

转载于:https://www.cnblogs.com/cxmsky/p/3289116.html

最后

以上就是平常柚子为你收集整理的SQL_Server_2008完全学习之第十章触发器的全部内容,希望文章能够帮你解决SQL_Server_2008完全学习之第十章触发器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(111)

评论列表共有 0 条评论

立即
投稿
返回
顶部