SqlServer——触发器

  一:触发器基本知识 

  触发器是一种特殊的存储过程,但没有接口(输入输出参数),触发器是引发它们的事务的一部分,因为SqlServer自动将引发它们的SQL语句和触发器作为一个隐式事务,因此当触发器正确执行后,事务才认为是完整的,触发器也可已在触发器内部通过 rollback tran 来回滚事务,当触发的SQL语句是隐式事务时,只回滚引发触发器的SQL语句和触发器;是显式事务时,将撤销从最外层 begin tran 开始的所有操作。所以触发器通常用来实现对表实施复杂的完整性约束和强制业务规则,它是一种高级约束,定义在特定的表上,却引用其它表中的列。可以定义比用check约束更为复杂的约束。例如,无法用约束实现的强制完整性规则,审核,维护不规范数据。

  1、触发器的分类

触发器从 SQL 语句类型可分为DML触发器和DDL触发器。

  • DML触发器:在往表中 insert、update、delete 时被自动地触发;DML 触发器从触发作用可分为 Instead of  触发器 和 After 触发器
      • Instead of  触发器:也称为替代触发器,只能用与将触发器内部的代码替换用户提交的 DML 操作( insert、update、delete ),即只执行触发器代码,不执行用户提交的代码。作用于 表 或 视图;一种操作只能有一个 instead of 触发器。
      • After 触发器:在响应用户代码(DDL和DML操作均可)之后执行触发器代码。该触发器按语句触发而不是按行触发,即一条语句不管影响了多少行,After 触发器只能触发一次;并且只能作用于 表;一种操作可以有多个 After  触发器,使用sp_settriggerorder存储过程标记最先执行和最后执行的触发器;如果触发的 SQL语句违反了约束,则不触发After触发器,而由于Instead of  触发器在执行触发 SQL语句前触发,却可以。所以Instead of  触发器可以对约束进行一些预处理。
  • DDL触发器:对表、视图、存储过程等的 create、drop、alter 时触发。

2、触发器的 Inserted 表和 Deleted 表

  这两个表由系统来维护﹐它们存在于内存中而不是在数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行 完成后﹐与该触发器相关的这两个表也被删除。Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。 Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。用户可以用SELECT语句查询这两个临时表,但不允许进行修改。

Inserted 表和 Deleted 表没有索引,因此当表内数据较多且频繁引用表内数据时,应当将数据保存到一个临时表,为临时表创建索引。

比如我在表上制定了一个后触发器当插入了数据后往另外一个表也插入这条数据; 当我执行insert的一条数据后执行触发器的语句,往另外一个表插入数据; 问题来了 当我连续插入10条数据触发器的运行机制又是怎样的呢?   SqlServer与MySql不同的点在于SqlServer在执行完10条插入Sql语句才允许触发器内的语句.

对表的操作 Inserted Update Deleted 
Inserted 表 插入的新数据 更新后的数据 X
Deleted 表 X 更新前的数据 删除的数据

3、受影响的行数。

如下语句:

  select @c1=c1,@c2=c2,@c3=c3 from Inserted

如果并没有一行受到触发 触发器 的SQL语句的影响,那么变量@c1、@c2、@c3的值不会改变,仍然是原来的值,而当有多个行受到影响时,每一行都会对变量值进行修改,到最后,变量值只是最后一行的值。因此要先判断受影响的行数。

@@rowcount 函数 保存着上一条语句受影响的行数,或者用 select @count=count(1) from Inserted 来判断Inserted 表中的行数。

  

  

  

例1:

create trigger tr_1

on database

for Create_Table  --|| Drop_Table

as

raiserror(‘你不能创建表‘,16,1)

rollback      --可以进行回滚因为Create_table 是隐式事务

drop trigger tr_1 on database –-删除触发器时必须有on database指明是删除数据库上的触发器

DML触发器:
    当数据库操作中发生数据操作语言(DML)事件时,将调用DML触发器.
    
     DML触发器可以分为以下3种类型:
      1.AFTER 触发器:AFTER 触发器只能在表上指定 (后触发)
          在执行Insert Update Delete 语句操作之后执行 AFTER 触发器,制定AFTER与制定For相同. 
      2.INSTEAD OF触发器 (替代触发)
          可以对视图或表定义但一个 INSTEAD OF   Insert/Update/Delete触发器 只能有一个
      3.CLR触发器.可以是上面2种或者DDL触发器

DML触发器细分为4种类型
        Insert触发器
        Delete触发器
        Update触发器
        以上几种类型的混合配饰触发器

①一个表可以有多个后触发器,但只能有一个替代触发器    视图上只能有替代触发器不能有后触发器

AFTER 触发器(后触发)

实例1:

if exists(select * from sysobjects where name=‘tr_3‘)

drop trigger tr_3

Go

Create trigger tr_3

on Employee

for update   –-当执行完了update语句后才会跳到我们后面定义的语句块

as

if update(CardID)    –-判断是否对某一列进行了更改

raiserror(‘你不更改卡号ID‘,16,1)

实例2:

if exists(select * from sysobjects where name=‘tr_4‘)

drop trigger tr_4

Go

Create trigger tr_4

on Employee

for delete

as

raiserror(‘不能删除员工‘,16,1)

②所谓的后触发就是执行完了对应的操作才执行我们定义的触发器内的语句块

INSTEAD OF触发器 (替代触发) :

实例1:

if exists(select * from sysobjects where name=‘tr_5‘)

drop trigger tr_5

Go

Create trigger tr_5

on Employee

instead of delete –替代了删除事件

as

select * from deleted  --看看临时deleted表里面有什么

delete from pay where CardID in (select CardID from deleted)  --先删子表再删基表

执行delete from Employee where CardID in (select CardID from deleted)

③[所谓的替代触发就是不执行对应的操作而执行我们定义触发器内的语句块

触发器使用的inserted临时表和deleted临时表:[无论是后触发还是替代触发都产生这2个临时表]:

虚拟表Inserted                             虚拟表Deleted
 执行Update时  将更新数据放到Inserted临时表       将原来的数据放进Deleted的临时表
 执行Insert时    将插入的数据放到Inserted临时表                        /
 执行Delete时                   /                                  将删除的数据放到deleted临时表

l.两个表的结构与激活触发器的原数据表结构相同。
2. 用INSERT语句插入记录激活触发器时,系统在原表插入记录的同时,也自动把记录插入到inserted临时表。
3. 用Delete语句删除记录激活触发器时,系统在原表删除记录的同时,会把删除的记录添加到deleted临时表。
4. 用UPDATE语句修改数据激活触发器时,系统先在原表删除原有记录,删除的记录被添加到deleted临时表,然后再插入新记录,并同时插入到inserted临时表。
5. 用户可以用SELECT语句查询这两个临时表,但不允许进行修改。
6. 触发器一旦执行完成,这两个表将被自动删除。

SqlServer的触发原理是:

比如我在表上制定了一个后触发器当插入了数据后往另外一个表也插入这条数据

当我执行insert的一条数据后 执行触发器的语句  往另外一个表插入数据

问题来了 当我连续插入10条数据 触发器的运行机制又是怎样的呢?

SqlServer与MySql不同的点在于SqlServer在执行完10条插入Sql语句才允许触发器内的语句.

而MySql是行级触发  也就是插入一条数据就执行触发器内的语句

时间: 2024-12-12 05:36:41

SqlServer——触发器的相关文章

一次SQLSERVER触发器编写感悟

背景:BOSS须要我写一个工厂採集端到服务器端的数据同步触发器,数据库採用的是sqlserver2008 需求:将多台採集机的数据同步到server中,假设採集端数据库与server数据库连接失败则将数据保存到记录表中 前期思路:从採集端创建server端的数据库链接,通过採集端的insert,update触发.同一时候往远程表写入 问题:因为初始接触sqlserver.对sqlserver触发器了解不深.查阅一些资料后写出了满足正常情况下(连接服务器数据库正常)的触发器. create tri

sqlserver 触发器实例

实例1:update USE [数据库名称]GO/****** Object: Trigger [dbo].[触发器名称] Script Date: 05/08/2014 12:40:25 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER TRIGGER [dbo].[T_触发器名称] ON [dbo].[表名称] FOR UPDATEAS DECLARE @Id VARCHAR(32), @remain_cost DECIMAL

SQLServer 触发器入门

阅读目录 一:触发器的优点 二:触发器的作用 三:触发器的分类 四:触发器的工作原理 五:创建触发器 六:管理触发器 概念:   触发器(trigger)是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对一个表进行操作( insert,delete, update)时就会激活它执行.触发器经常用于加强数据的完整性约束和业务规则等. 触发器可以从 DBA_TRIGGERS ,U

sqlserver 触发器

 何为触发器? 在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序.触发器是一个特殊的存储过程,它不能被显式地调用﹐而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活.所以触发器可以用来实现对表实施复杂的完整性约束. SQL Server为每个触发器都创建了两个专用表:Inserted表和Deleted表.Deleted和Inserted分别代表出发事件的表“旧的一条记录”和“新的一条记录”.这两个表由系统来维护﹐它们存在于内存中而不是在数据库中.这两

SQLServer触发器

触发器的作用: 自动化操作,减少了手动操作以及出错的几率. 触发器是一种特殊类型的存储过程,它不同于前面介绍过的一般的存储过程. [在SQL内部把触发器看做是存储过程但是不能传递参数] 一般的存储过程通过存储过程名称被直接调用,而触发器主要是通过事件进行触发而被执行. 触发器是一个功能强大的工具,在表中数据发生变化时自动强制执行. 触发器可以用于SQL Server约束.默认值和规则的完整性检查,还可以完成难以用普通约束实现的复杂功能. 那究竟何为触发器?在SQL Server里面也就是对某一个

SQLServer 触发器初探

继上次的SQL Server空间化任务之后, 笔者又接到新的任务: 当数据库属性字段发生变化时,在不改变业务代码的条件下,自动更新空间数据. 首先想到的解决方案就是触发器. 基本思路: 在数据更新或插入完毕之后,当表的x,y字段任意一个的值发生变化时,即开始更新空间字段数据. 下面以摄像机表videopointinfo为例 字段 类型 说明 videoid varchar 主键ID videoname varchar 摄像机名 clientx number 经度 clienty number 纬

SQLServer触发器的使用

创建: [sql] view plain copy create trigger trigger_name on {table_name view_name} {for After Instead of } [ insert, update,delete ] as sql_statement 删除触发器: [sql] view plain copy drop trigger trigger_name 查看数据库中已有触发器: [sql] view plain copy use jxcSoftwa

sqlserver 触发器语法

语法:Trigger on an INSERT, UPDATE, or DELETE statement to a table or view (DML Trigger)CREATE TRIGGER [ schema_name . ]trigger_name ON { table | view } [ WITH <dml_trigger_option> [ ,...n ] ]{ FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] [

SqlServer触发器实现表的级联插入、级联更新

首先建立两张表,分别为test1与test2,期望在更改test1的时候,test2的相关记录能够同时做出更改.假定test1与test2的表结构相同,如下表所示 name age     触发器实现级联插入: create trigger test3 on test1 after insert as insert into test2 select name,age from inserted 触发器实现级联更新: create trigger test4 on test1 after upd