sql server 触发器

触发器 是一种特殊类型的存储过程。触发器可包含复杂的T-SQL语句。触发器不能通过名称被直接调用,也不允许设置参数。它是建立在触发事件上的。

触发器可以强制执行一定的业务规则,以保持数据完整性、检查数据有效性、实现数据库管理任务和一些附加功能。

触发器的分类: DML、 DDL、 登录触发器

创建触发器需要指定的选项:

1.触发器的名称。

2.在其上定义触发器的表。

3.触发器将何时激发。

4.激活触发器的数据修改语句。

5.执行触发操作的编程语句。

CREATE TRIGGER语句基本语法格式如下:

CREATE TRIGGER 触发器名称

ON {表名 | 视图名}

[with encryption]

{

{ {FOR | AFTER | INSTEAD OF}

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

AS

sql_statement […n ]

}

其中:

AFTER

指定触发器只有在触发 SQL 语句中指定的所有操作都已成功执行后才激发。所有的引用级联操作和约束检查也必须成功完成后,才能执行此触发器。如果仅指定 FOR 关键字,则 AFTER 是默认设置。

INSTEAD OF

指定执行触发器而不是执行触发 SQL 语句,从而替代触发语句的操作。

/*在student表上创建触发器,
在用户插入、修改和删除记录时,都会自动显示表中的内容:*/

use test
go

create trigger trig_1 on student
after insert,delete,update
as 
begin
    set nocount on
    select * from student
end

insert student(sno) values(5)

delete student where sno=5


exec sp_helptext trig_1    --查看触发器内容 
exec sp_helptrigger student   --查看表上的触发器的属性
select * from sysobjects where xtype='TR'  --查看数据库中已有的触发器


drop trigger trig_1

inserted表和deleted表

触发器执行的时候,产生两个临时表: inserted表 和 deleted表 。它们的结构和所在的表的结构相同,可使用这两个表测试某些数据修改的效果和设置触发器操作的条件,但不能对表中的数据进行更改。

deleted表用于存储DELETE和UPDATE语句所影响的行的副本。在执行delete或update语句时,行从触发器表中删除,并传输到deleted表中。

inserted表用于存储INSERT和UPDATE语句所影响的行的副本。在插入和更新时,新建行被同时添加到inserted表和触发器表中。Inserted表中的行是触发器表中新行的副本。

在对具有触发器的表(触发器表)进行操作时,有:

执行INSERT操作,插入到触发器表中的新行被插入到inserted表中。

执行DELETE操作,从触发器表中删除的行被插入到deleted表中。

执行UPDATE操作,先从触发器表中删除旧行,然后再插入新行。删除的旧行插入到deleted表中;更改后的新行被插入到inserted 表中。

使用DML触发器

1. INSERT和UPDATE触发器

当向表中插入或者更新记录时,INSERT或者UPDATE触发器被激活。一般情况下,这两种触发器常用来检查插入或者修改后的数据是否满足要求。

INSERT触发器被触发时,新的记录增加到触发器的对应表中,并且同时也添加到一个inserted表中。

修改一个记录等于插入了一个新的记录并且删除一个旧的记录。当在一个有UPDATE触发器的表中修改记录时,表中原来的记录被移动到deleted表中,修改过的记录插入到了插入表中,触发器可以参考deleted表和inserted表以及被修改的表,以确定如何完成数据库操作。

2. DELETE触发器

DELETE触发器通常用于下面的情况:

防止那些确实要删除,但是可能会引起数据一致性问题的情况,一般是用于那些用作其他表的外部键记录。

用于级联删除操作。

例如:

/*例:下例说明inserted表和deleted表的作用*/

if exists(select name from sysobjects where name='trig_2' and type='TR')
    drop trigger trig_2
go

create trigger trig_2 
on student
after update                         --update触发器
as 
    print 'inserted表'
    select * from inserted
    print 'deleted表'
    select * from deleted
go
set nocount on
update student set sname='关二' where sno=2
--drop trigger trig_2


create trigger trig_3 
on student
after insert                         --insert触发器
as 
    print 'inserted表'
    select * from inserted
    print 'deleted表'
    select * from deleted
go
insert student values(100,'刘一百','男',25)
drop trigger trig_3


create trigger trig_4 
on student
after delete                         --delete触发器
as 
    print 'inserted表'
    select * from inserted
    print 'deleted表'
    select * from deleted
go
delete student where sno=100
drop trigger trig_4

修改触发器

语法格式:

ALTER TRIGGER trigger_name

ON ( table | view )

{

{ ( FOR | AFTER | INSTEAD OF ) }

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

AS

sql_statement […n ]

}

DDL触发器使用

例如:

/*DDL触发器*/

/*在test数据库上创建一个DDL触发器safe,
用来防止数据库中的任一表被修改或删除。*/

create trigger safetest
on database                         --数据库DDL触发器
after drop_table,alter_table
as
begin
    raiserror('不能修改表结构',16,2)
    rollback
end
go

--执行以下程序,观察结果
alter table student add nation char(10)

disable trigger safetest on database
drop trigger safetest on database
---------------------------------------------------------


/*在服务器上创建一个DDL触发器tablecreat,
用来防止在服务器上创建数据库*/

create trigger trig_last
on all server
after create_database
as
begin
    raiserror('不能创建新的数据库',16,2)
    rollback
end
go

--执行以下程序,观察结果
create database test_trig

disable trigger trig_last on all server
drop trigger trig_last on all server

删除触发器

使用SQL Server Management Studio删除触发器

使用DROP TRIGGER语句来删除触发器。其语法格式如下:

DROP TRIGGER { trigger } [ , …n ]

触发器禁用和启用

例如:

/*触发器禁用和启用*/

/*禁用sc表上的触发器trig_g。*/
alter table sc disable trigger trig_g
disable trigger trig_g on sc
go

/*启用sc表上的触发器trig_g。*/
alter table sc enable trigger trig_g
enable trigger trig_g on sc
go

--执行以下程序,观察结果
insert into sc values(1,100,1,-50)
select * from sc

触发器具体应用

例如:

/*具体应用*/

/*创建触发器trig3,
当删除student表中的学生记录时,
应该同时删除sc表中对应的记录*/

create trigger trig_5
on student
for delete
as 
 delete sc
 where sc.sno in(select sno from deleted)
go

select * from student
select * from sc
go

/*exec sp_help score   --查看其中外键

alter table score         --删除外键
drop CONSTRAINT FK_score_course

alter table score
drop CONSTRAINT FK_score_student*/


delete student where sno=3
go

select * from student
select * from sc 
-------------------------------------------------------------


create trigger trig_g 
on sc
after insert,update
as
begin
    declare @g int
    select @g=grade from inserted
    if @g<0
    begin
         select '成绩必须>=0'
         rollback
    end
end
go

--执行以下程序,观察结果
insert into sc values(1,10,1,50)
select * from sc


/*例: 建立一个修改触发器trigno,
该触发器防止用户修改表student的学号*/

create trigger trigno
on student
after update
as
if update(sno)
    begin
        raiserror('不能修改学号',16,2)
        rollback
    end
go

--执行以下程序,观察结果
update student set sno='2' where sno='1'
select * from student
------------------------------------------------------


/*INSTEAD OF触发器*/

/*例:在student表上创建一个INSTEAD OF触发器trig_6,
当用户插入数据时注意观察触发器的执行。*/

create trigger trig_6
on student
instead of insert
as
    select * from student
go

--执行以下程序,观察结果
insert into student(sno,sname) values('300','白扯')

博客园博客:欠扁的小篮子

坚持原创技术分享,您的支持将鼓励我继续创作!
0%