触发器是一种特殊类型的存储过程。们介绍的存储过程。

触发器主要是通过事件进行触发被自己主动调用运行的。

而存储过程能够通过存储过程的名称被调用。

Ø 什么是触发器

触发器对表进行插入、更新、删除的时候会自己主动运行的特殊存储过程。触发器一般用在check约束更加复杂的约束上面。触发器和普通的存储过程的差别是:触发器是当对某一个表进行操作。

诸如:update、insert、delete这些操作的时候,系统会自己主动调用运行该表上相应的触发器。SQL Server 2005中触发器能够分为两类:DML触发器和DDL触发器。当中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句。

DML触发器分为:

1、 after触发器(之后触发)

a、 insert触发器

b、 update触发器

c、 delete触发器

2、 instead of 触发器 (之前触发)

当中after触发器要求仅仅有运行某一操作insert、update、delete之后触发器才被触发。且仅仅能定义在表上。而instead of触发器表示并不运行其定义的操作(insert、update、delete)而仅是运行触发器本身。既能够在表上定义instead of触发器,也能够在视图上定义。

触发器有两个特殊的表:插入表(instered表)和删除表(deleted表)。这两张是逻辑表也是虚表。

有系统在内存中创建者两张表。不会存储在数据库中。并且两张表的都是仅仅读的,仅仅能读取数据而不能改动数据。这两张表的结果总是与被改触发器应用的表的结构同样。当触发器完毕工作后,这两张表就会被删除。

Inserted表的数据是插入或是改动后的数据,而deleted表的数据是更新前的或是删除的数据。

对表的操作

Inserted逻辑表

Deleted逻辑表

添加记录(insert)

存放添加的记录

删除记录(delete)

存放被删除的记录

改动记录(update)

存放更新后的记录

存放更新前的记录

Update数据的时候就是先删除表记录,然后添加一条记录。

这样在inserted和deleted表就都有update后的数据记录了。注意的是:触发器本身就是一个事务。所以在触发器里面能够对改动数据进行一些特殊的检查。假设不满足能够利用事务回滚,撤销操作。

Ø 创建触发器

语法

create trigger tgr_name
on table_name
with encrypion –加密触发器
for update...
as
Transact-SQL

# 创建insert类型触发器

--创建insert插入类型触发器
if (object_id('tgr_classes_insert', 'tr') is not null)
drop trigger tgr_classes_insert
go
create trigger tgr_classes_insert
on classes
for insert --插入触发
as
--定义变量
declare @id int, @name varchar(20), @temp int;
--在inserted表中查询已经插入记录信息
select @id = id, @name = name from inserted;
set @name = @name + convert(varchar, @id);
set @temp = @id / 2;
insert into student values(@name, 18 + @id, @temp, @id);
print '加入学生成功。';
go
--插入数据
insert into classes values('5班', getDate());
--查询数据
select * from classes;
select * from student order by id;

insert触发器,会在inserted表中加入一条刚插入的记录。

# 创建delete类型触发器

--delete删除类型触发器
if (object_id('tgr_classes_delete', 'TR') is not null)
drop trigger tgr_classes_delete
go
create trigger tgr_classes_delete
on classes
for delete --删除触发
as
print '备份数据中……';
if (object_id('classesBackup', 'U') is not null)
--存在classesBackup。直接插入数据
insert into classesBackup select name, createDate from deleted;
else
--不存在classesBackup创建再插入
select * into classesBackup from deleted;
print '备份数据成功!';
go
--
--不显示影响行数
--set nocount on;
delete classes where name = '5班';
--查询数据
select * from classes;
select * from classesBackup;

delete触发器会在删除数据的时候,将刚才删除的数据保存在deleted表中。

# 创建update类型触发器

--update更新类型触发器
if (object_id('tgr_classes_update', 'TR') is not null)
drop trigger tgr_classes_update
go
create trigger tgr_classes_update
on classes
for update
as
declare @oldName varchar(20), @newName varchar(20);
--更新前的数据
select @oldName = name from deleted;
if (exists (select * from student where name like '%'+ @oldName + '%'))
begin
--更新后的数据
select @newName = name from inserted;
update student set name = replace(name, @oldName, @newName) where name like '%'+ @oldName + '%';
print '级联改动数据成功!';
end
else
print '无需改动student表! ';
go
--查询数据
select * from student order by id;
select * from classes;
update classes set name = '五班' where name = '5班';

update触发器会在更新数据后,将更新前的数据保存在deleted表中,更新后的数据保存在inserted表中。

# update更新列级触发器

if (object_id('tgr_classes_update_column', 'TR') is not null)
drop trigger tgr_classes_update_column
go
create trigger tgr_classes_update_column
on classes
for update
as
--列级触发器:是否更新了班级创建时间
if (update(createDate))
begin
raisError('系统提示:班级创建时间不能改动。', 16, 11);
rollback tran;
end
go
--測试
select * from student order by id;
select * from classes;
update classes set createDate = getDate() where id = 3;
update classes set name = '四班' where id = 7;

更新列级触发器能够用update是否推断更新列记录;

# instead of类型触发器

instead of触发器表示并不运行其定义的操作(insert、update、delete)而仅是运行触发器本身的内容。

创建语法

create trigger tgr_name
on table_name
with encryption
instead of update...
as
T-SQL

# 创建instead of触发器

if (object_id('tgr_classes_inteadOf', 'TR') is not null)
drop trigger tgr_classes_inteadOf
go
create trigger tgr_classes_inteadOf
on classes
instead of delete/*, update, insert*/
as
declare @id int, @name varchar(20);
--查询被删除的信息。病赋值
select @id = id, @name = name from deleted;
print 'id: ' + convert(varchar, @id) + ', name: ' + @name;
--先删除student的信息
delete student where cid = @id;
--再删除classes的信息
delete classes where id = @id;
print '删除[ id: ' + convert(varchar, @id) + ', name: ' + @name + ' ] 的信息成功。';
go
--test
select * from student order by id;
select * from classes;
delete classes where id = 7;

# 显示自己定义消息raiserror

if (object_id('tgr_message', 'TR') is not null)
drop trigger tgr_message
go
create trigger tgr_message
on student
after insert, update
as raisError('tgr_message触发器被触发', 16, 10);
go
--test
insert into student values('lily', 22, 1, 7);
update student set sex = 0 where name = 'lucy';
select * from student order by id;

# 改动触发器

alter trigger tgr_message
on student
after delete
as raisError('tgr_message触发器被触发', 16, 10);
go
--test
delete from student where name = 'lucy';

# 启用、禁用触发器

--禁用触发器
disable trigger tgr_message on student;
--启用触发器
enable trigger tgr_message on student;

# 查询创建的触发器信息

--查询已存在的触发器
select * from sys.triggers;
select * from sys.objects where type = 'TR'; --查看触发器触发事件
select te.* from sys.trigger_events te join sys.triggers t
on t.object_id = te.object_id
where t.parent_class = 0 and t.name = 'tgr_valid_data'; --查看创建触发器语句
exec sp_helptext 'tgr_message';

# 演示样例。验证插入数据

if ((object_id('tgr_valid_data', 'TR') is not null))
drop trigger tgr_valid_data
go
create trigger tgr_valid_data
on student
after insert
as
declare @age int,
@name varchar(20);
select @name = s.name, @age = s.age from inserted s;
if (@age < 18)
begin
raisError('插入新数据的age有问题', 16, 1);
rollback tran;
end
go
--test
insert into student values('forest', 2, 0, 7);
insert into student values('forest', 22, 0, 7);
select * from student order by id;

# 演示样例,操作日志

if (object_id('log', 'U') is not null)
drop table log
go
create table log(
id int identity(1, 1) primary key,
action varchar(20),
createDate datetime default getDate()
)
go
if (exists (select * from sys.objects where name = 'tgr_student_log'))
drop trigger tgr_student_log
go
create trigger tgr_student_log
on student
after insert, update, delete
as
if ((exists (select 1 from inserted)) and (exists (select 1 from deleted)))
begin
insert into log(action) values('updated');
end
else if (exists (select 1 from inserted) and not exists (select 1 from deleted))
begin
insert into log(action) values('inserted');
end
else if (not exists (select 1 from inserted) and exists (select 1 from deleted))
begin
insert into log(action) values('deleted');
end
go
--test
insert into student values('king', 22, 1, 7);
update student set sex = 0 where name = 'king';
delete student where name = 'king';
select * from log;
select * from student order by id;

版权声明:本文博主原创文章,博客,未经同意不得转载。

SQL Server 板机的更多相关文章

  1. sql server 本机编译存储过程(内存优化表) 绕过不支持FULL OUTER JOIN 的限制的方法

    将FULL OUTER JOIN 转成left join,right join 和 union select * from A ID NAME4 Spaghetti1 Pirate2 Monkey3 ...

  2. SQL Server中关于跟踪(Trace)那点事

    前言 一提到跟踪俩字,很多人想到警匪片中的场景,同样在我们的SQL Server数据库中“跟踪”也是无处不在的,如果我们利用好了跟踪技巧,就可以针对某些特定的场景做定向分析,找出充足的证据来破案. 简 ...

  3. 【转】SQL Server中关于跟踪(Trace)那点事

    前言 一提到跟踪俩字,很多人想到警匪片中的场景,同样在我们的SQL Server数据库中“跟踪”也是无处不在的,如果我们利用好了跟踪技巧,就可以针对某些特定的场景做定向分析,找出充足的证据来破案. 简 ...

  4. 安装SQL Server 2005

    在安装SQL Server 2005时,经常会遇到一些错误,从而使系统无法正常安装.下面讲解在安装过程中经常出现的一些错误及其解决的方法.1.解决在安装SQL Server 2005时安装程序被挂起的 ...

  5. 配置SQL Server 2008服务器

    怎么配置SQL Server 2008服务器_百度经验 http://jingyan.baidu.com/article/9faa7231a922c1473c28cb23.html 1.验证安装是否成 ...

  6. 安装 SQL Server 2005 的硬件和软件要求(官方全面)

    SQL Server 2005 安装要求 本主题介绍了安装 SQL Server 205 的硬件和软件要求,以及查看安装文档的说明. 硬件和软件要求(32 位和 64 位) 访问 SQL Server ...

  7. SQL Server FileStream优点与不足

    LOB优点: 1.保证大对象的事务一致性. 2.备份与还原包括大数据对象,可以对它进行时点恢复. 3.所有数据都可以使用一种存储与查询环境. LOB不足: 1.大型对象在缓存中占非常大的缓存区. 2. ...

  8. Amazon RDS 上的 Microsoft SQL Server » 导入和导出 SQL Server 数据库

    导入和导出 SQL Server 数据库 Amazon RDS 支持使用完整备份文件 (.bak 文件) 对 Microsoft SQL Server 数据库进行本机备份和还原.您可以在单个便携式文件 ...

  9. SQL Server中关于跟踪(Trace)那点事(转载)

    前言 一提到跟踪俩字,很多人想到警匪片中的场景,同样在我们的SQL Server数据库中“跟踪”也是无处不在的,如果我们利用好了跟踪技巧,就可以针对某些特定的场景做定向分析,找出充足的证据来破案. 简 ...

随机推荐

  1. Redis测井系统

    什么是 SLOWLOG Slow log 是 Redis 用来记录查询运行时间的日志系统. 查询运行时间指的是不包含像client响应(talking).发送回复等 IO 操作,而单单是运行一个查询命 ...

  2. Java网络编程注意事项3

    如何使用POST请求和GET请求Web网站发送请求,下面的参考代码: import java.io.BufferedReader; import java.io.InputStream; import ...

  3. SQL Server 移动数据库

    原文:SQL Server 移动数据库 移动系统数据库在下列情况下可能很有用: 故障恢复.例如,数据库处于可疑模式下或因硬件故障而关闭. 计划的重定位. 为预定的磁盘维护操作而进行的重定位. 下列过程 ...

  4. Java IO的RandomAccessFile的使用(转)

    现有如下的一个需求,向已存在1G数据的txt文本里末尾追加一行文字,内容如下“Lucene是一款非常优秀的全文检索库”.可能大多数朋友会觉得这个需求很easy,说实话,确实easy,然后XXX君开始实 ...

  5. Android开发自学笔记(基于Android Studio1.3.1)—1.环境搭建(转)

    一.引言    本套学习笔记的开发环境是Windows 10 专业版和Android Studio 的最新版1.3.1. Android Studio 是一个Android开发环境,基于Intelli ...

  6. css3 翻牌(rotate) 以及翻转 导致边缘锯齿解决 方法

     主要知识点:rotate旋转以及  outline透明的像素消除(明显降低)火狐旋转是产生的 锯齿  首先看结构: <li class="flip-container " ...

  7. hadoop2.0的datanode数据存储文件夹策略的多个副本

    在hadoop2.0在,datanode数据存储盘选择策略有两种方式复制: 首先是要遵循hadoop1.0磁盘文件夹投票,实现类:RoundRobinVolumeChoosingPolicy.java ...

  8. React的React Native

    React的React Native React无疑是今年最火的前端框架,github上的star直逼30,000,基于React的React Native的star也直逼20,000.有了React ...

  9. 原子操作(atomic operation)

    深入分析Volatile的实现原理 引言 在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共 ...

  10. ORA-00838: Specified value of MEMORY_TARGET is too small(转)

    1. 测试环境OS: RHEL5U5(32bit)DB: Oracle 11.2.0.3.0(32bit) 2.   异常原因. 2.1 oracle 11g默认sga_target为0,如下图, O ...