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

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

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

Ø 什么是触发器

触发器对表进行插入、更新、删除的时候会自己主动运行的特殊存储过程。触发器一般用在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. ASP.NET之AdRotator实现淘宝浏览页面的商品随机推荐功能

    如今随便上个网都能够看到淘宝.京东等各大电商平台的双十一购物狂欢宣传,从2009年開始淘宝愣是把11.11这一天打造成了全民购物狂欢节.阿里巴巴的上市更是激发了阿里人的斗志,据说他们今年的目标是100 ...

  2. Bulk Insert具体订单

    Bulk Insert具体订单 BULK INSERT与用户指定的格式的数据文件复制到数据库表或视图. 语法: BULK INSERT [ [ 'database_name'.][ 'owner' ] ...

  3. Bash多个配置文件通常用于

    Login shells阅读下面的启动文件: 文件 内容 /etc/profile 对全部用户开放的全局配置文件 ~/.bash_profile 某个用户个人的启动文件,能用作个人的全局设置 ~/.b ...

  4. [LeetCode] Combinations [38]

    称号 Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exa ...

  5. 【Flume】flume于transactionCapacity和batchSize进行详细的分析和质疑的概念

    我不知道你用flume读者熟悉无论这两个概念 一开始我是有点困惑,? 没感觉到transactionCapacity的作用啊? batchSize又是干啥的啊? -- -- 带着这些问题,我们深入源代 ...

  6. java这些东西发展(1)-------大约ORA00604和ORA12705

    ******************************有关myEclipse和oracle在连接发生的一个问题********************************* 用户界面显示的评 ...

  7. NUnit3 Test Adapter vs2015

    NUnit的安装 前言:NUnit是什么? NUnit 是一个单元测试框架,专门针对于.NET来写的.NUnit是xUnit家族种的第4个主打产品,完全由C#语言来编写,并且编写时充分利用了许多.NE ...

  8. Cordova WP8 插件开发

    原文:Cordova WP8 插件开发 前面博客中介绍了Cordova WP8平台上的安装部署,Cordova扩展可以利用WP8本地代码扩展WebApp的功能,调用本地能力需要开发相应的插件,下面以闪 ...

  9. js 性能优化整理之 高频优化

    mousemove 拖拽操作 var count = 0; elem.onmousemove = function(){ count++; // 当计数器为偶数的时候不执行mousemove if( ...

  10. android 内存泄漏分析技巧

    java虚拟机执行一般都有一个内存界限,超过这个界限,就会报outofmemory.这个时候一般都是存在内存泄漏.解决内存泄漏问题,窃以为分为两个步骤:分析应用程序是否真的有内存泄漏,找到内存泄漏的地 ...