INSTEAD OF触发器工作原理

INSTEAD OF表示并不执行其所定义的操作INSERT,UPDATE ,DELETE,而仅是执行触发器本身,即当对表进行INSERT、UPDATE 或 DELETE 操作时,系统不是直接对表执行这些操作,而是把操作内容交给触发器,让触发器检查所进行的操作是否正确,如正确才进行相应的操作。因此,INSTEAD OF 触发器的动作要早于表的约束处理。
既可以在表上定义INSTEAD OF触发器,也可以在视图上定义。

传递给为表定义的 INSTEAD OF 触发器的插入的和删除的表与传递给 AFTER 触发器的插入的和删除的表遵守相同的规则。 插入的和删除的表的格式与在其上定义 INSTEAD OF 触发器的表的格式相同。 插入的和删除的表中的每一列都直接映射到基表中的列。

以下是关于引用带 INSTEAD OF 触发器的表的 INSERT 或 UPDATE 语句何时必须提供列值的规则,当引用的表不带 INSTEAD OF 触发器时也一样:

  • 不能为计算列或具有 timestamp 数据类型的列指定值。

  • 不能为具有 IDENTITY 属性的列指定值,除非该表的 IDENTITY_INSERT 为 ON。 当 IDENTITY_INSERT 为 ON 时,INSERT 语句必须提供一个值。

  • INSERT 语句必须为所有无 DEFAULT 约束的 NOT NULL 列提供值。

  • 对于除计算,identity 之外的任何列或timestamp列值都是可选的任何允许空值的列或列具有 DEFAULT 定义的 NOT NULL。

    当 INSERT、UPDATE 或 DELETE 语句引用具有 INSTEAD OF 触发器的视图时, 数据库引擎 将调用该触发器,而不是对任何表采取任何直接操作。 即使插入的和删除的表中为该视图生成的信息格式不同于基表中的数据格式,触发器也必须使用插入的和删除的表中的信息来生成实现基表中请求的操作所需的任何语句。

INSTEAD OF触发器创建

语法:

--声明数据库应用。
use 数据库名;
go

--判断是否已存在触发器,如果已存在则删除。
if exists(select * from sysobjects where name=触发器名)
drop trigger 触发器名;
go

--执行创建触发器
create

--触发器关键字
trigger

--DML 触发器所属架构的名称。 DML 触发器的作用域是为其创建该触发器的表或视图的架构。 不能为 DDL 或登录触发器指定
--[dbo.]
--触发器名称
[架构名.]{ 表名 | 视图名}

on

--对其执行 DML 触发器的表或视图,有时称为触发器表或触发器视图。 可以根据需要指定表或视图的完全限定名称。 视图只能被 INSTEAD OF 触发器引用。 不能对局部或全局临时表定义 DML 触发器。
[架构名.]触发器名

with
--对CREATE TRIGGER 语句的文本进行模糊处理。使用WITH ENCRYPTION可以防止将触发器作为SQL Server复制的一部分进行发布。不能为 CLR 触发器指定 WITH ENCRYPTION。(指定此选项将为触发器加密)
[encryption][,]

--指示触发器已本机编译。 (只能应用于table)
--内存优化表上的触发器需要使用此选项。
--[native_compilation][,]

--确保不能删除或更改触发器引用的表。(只能应用于table)
--内存优化表上的触发器需要使用此选项,但此选项不支持传统表上的触发器。
[schemabinding][,]

--EXECUTE AS (后面可以跟函数,存储过程等)
--指定用于执行该触发器的安全上下文。 允许您控制 SQL Server 实例用于验证被触发器引用的任意数据库对象的权限的用户帐户。
--内存优化表上的触发器需要使用此选项。
--[execute as clause]

--指定执行 DML 触发器而不是触发 SQL 语句,因此,其优先级高于触发语句的操作。 不能为 DDL 或登录触发器指定 INSTEAD OF。
--对于表或视图,每个 INSERT、UPDATE 或 DELETE 语句最多可定义一个 INSTEAD OF 触发器。 但是,可以为具有自己的 INSTEAD OF 触发器的多个视图定义视图。
--INSTEAD OF 触发器不可以用于使用 WITH CHECK OPTION 的可更新视图。 如果将 INSTEAD OF 触发器添加到指定了 WITH CHECK OPTION 的可更新视图中,则 SQL Server 将引发错误。 用户须用 ALTER VIEW 删除该选项后才能定义 INSTEAD OF 触发器。
instead of

--指定数据修改语句,这些语句可在 DML 触发器对此表或视图进行尝试时激活该触发器。 必须至少指定一个选项。 在触发器定义中允许使用上述选项的任意顺序组合。
--对于 INSTEAD OF 触发器,不允许对具有指定级联操作 ON DELETE 的引用关系的表使用 DELETE 选项。 同样,也不允许对具有指定级联操作 ON UPDATE 的引用关系的表使用 UPDATE 选项。
{ [insert] [,] [update] [,] [delete] }

--指定应该再添加一个现有类型的触发器。 WITH APPEND 不能与 INSTEAD OF 触发器一起使用。如果显式声明了 AFTER 触发器,则也不能使用该子句。
--仅当为了向后兼容而指定了 FOR 时(但没有 INSTEAD OF 或 AFTER)时,才能使用 WITH APPEND。 如果指定了 EXTERNAL NAME(即触发器为 CLR 触发器),则不能指定 WITH APPEND。
--with append

--指示当复制代理修改涉及到触发器的表时,不应执行触发器。
--not for replication
as
begin

  sql_statement
end
go

示例:

--声明数据库应用。
use testss;
go

--判断是否已存在触发器,如果已存在则删除。
if exists(select * from sysobjects where name='insteadoftri')
drop trigger insteadoftri;
go

--执行创建触发器
create

--触发器关键字
trigger

--DML 触发器所属架构的名称。 DML 触发器的作用域是为其创建该触发器的表或视图的架构。 不能为 DDL 或登录触发器指定
--[dbo.]
--触发器名称
dbo.insteadoftri

on

--对其执行 DML 触发器的表或视图,有时称为触发器表或触发器视图。 可以根据需要指定表或视图的完全限定名称。 视图只能被 INSTEAD OF 触发器引用。 不能对局部或全局临时表定义 DML 触发器。
dbo.test1

with
--对CREATE TRIGGER 语句的文本进行模糊处理。使用WITH ENCRYPTION可以防止将触发器作为SQL Server复制的一部分进行发布。不能为 CLR 触发器指定 WITH ENCRYPTION。(指定此选项将为触发器加密)
encryption,

--指示触发器已本机编译。 (只能应用于table)
--内存优化表上的触发器需要使用此选项。
--[native_compilation][,]

--确保不能删除或更改触发器引用的表。(只能应用于table)
--内存优化表上的触发器需要使用此选项,但此选项不支持传统表上的触发器。
schemabinding

--EXECUTE AS (后面可以跟函数,存储过程等)
--指定用于执行该触发器的安全上下文。 允许您控制 SQL Server 实例用于验证被触发器引用的任意数据库对象的权限的用户帐户。
--内存优化表上的触发器需要使用此选项。
--[execute as clause]

--指定执行 DML 触发器而不是触发 SQL 语句,因此,其优先级高于触发语句的操作。 不能为 DDL 或登录触发器指定 INSTEAD OF。
--对于表或视图,每个 INSERT、UPDATE 或 DELETE 语句最多可定义一个 INSTEAD OF 触发器。 但是,可以为具有自己的 INSTEAD OF 触发器的多个视图定义视图。
--INSTEAD OF 触发器不可以用于使用 WITH CHECK OPTION 的可更新视图。 如果将 INSTEAD OF 触发器添加到指定了 WITH CHECK OPTION 的可更新视图中,则 SQL Server 将引发错误。 用户须用 ALTER VIEW 删除该选项后才能定义 INSTEAD OF 触发器。
instead of

--指定数据修改语句,这些语句可在 DML 触发器对此表或视图进行尝试时激活该触发器。 必须至少指定一个选项。 在触发器定义中允许使用上述选项的任意顺序组合。
--对于 INSTEAD OF 触发器,不允许对具有指定级联操作 ON DELETE 的引用关系的表使用 DELETE 选项。 同样,也不允许对具有指定级联操作 ON UPDATE 的引用关系的表使用 UPDATE 选项。
insert,update,delete

--指定应该再添加一个现有类型的触发器。 WITH APPEND 不能与 INSTEAD OF 触发器一起使用。如果显式声明了 AFTER 触发器,则也不能使用该子句。
--仅当为了向后兼容而指定了 FOR 时(但没有 INSTEAD OF 或 AFTER)时,才能使用 WITH APPEND。 如果指定了 EXTERNAL NAME(即触发器为 CLR 触发器),则不能指定 WITH APPEND。
--with append

--指示当复制代理修改涉及到触发器的表时,不应执行触发器。
not for replication
as
begin
if (select count(1) from inserted) = 1 and (select count(1) from deleted) = 0
begin
print('insert');
insert into dbo.test1(name,sex,age,classid,height,xml1,xml2)
select top 1 name,sex,age,classid,height,xml1,xml2 from inserted order by id desc;
end
else if (select count(1) from deleted) = 1 and (select count(1) from inserted) = 0
begin
print('delete');
delete from dbo.test1 where id=(select top 1 id from deleted order by id desc);
end
else
begin
print('update');
update dbo.test1 set name=inserted.name,sex=inserted.sex,age=inserted.age,classid=inserted.classid,height=inserted.height,
xml1=inserted.xml1,xml2=inserted.xml2
from inserted
where dbo.test1.id=(select top 1 id from deleted order by id desc);
end
end
go

示例结果:

INSTEAD OF触发器优缺点

优点:

  1、可以实现在对数据操作之前更严格的检查和校验。

  2、可定义在表上,也可以定义在视图上,同一操作只能定义一个。

  3、指定执行 DML 触发器而不是触发 SQL 语句,因此,其优先级高于触发语句的操作。

缺点:

  1、可移植性差。

  2、占用服务器资源,给服务器造成压力。

  3、执行速度主要取决于数据库服务器的性能与触发器代码的复杂程度。

  4、触发器会使编程时源码的结构被迫打乱,为将程序修改、源码阅读带来困难。

SQLServer之创建INSTEAD OF INSERT,UPDATE,DELETE触发器的更多相关文章

  1. PHP5: mysqli 插入, 查询, 更新和删除 Insert Update Delete Using mysqli (CRUD)

    原文: PHP5: mysqli 插入, 查询, 更新和删除  Insert Update Delete Using mysqli (CRUD) PHP 5 及以上版本建议使用以下方式连接 MySQL ...

  2. SQLServer之创建DML AFTER INSERT触发器

    DML AFTER INSERT触发器创建原理 触发器触发时,系统自动在内存中创建deleted表或inserted表,内存中创建的表只读,不允许修改,触发器执行完成后,自动删除. insert触发器 ...

  3. insert update delete 语法 以及用法

    insert update delete 被称为 数据定义语句语句 也就是数据的增加 修改 删除 其中不包括查询 譬如: create database -创建数据库 alter database - ...

  4. sql中同一个Trigger里同时包含Insert,Update,Delete

    sql中同一个Trigger里同时包含Insert,Update,Delete SQLServer是靠Inserted表和Deleted表来处理的,判断一下就可以了,只不过比ORACLE麻烦一点 cr ...

  5. LINQ体验(9)——LINQ to SQL语句之Insert/Update/Delete操作

    我们继续讲解LINQ to SQL语句,这篇我们来讨论Insert/Update/Delete操作.这个在我们的程序中最为常用了.我们直接看例子. Insert/Update/Delete操作 插入( ...

  6. JDBC基础篇(MYSQL)——使用statement执行DML语句(insert/update/delete)

    注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接: package day02_statement; import java.sql.Connection; import java.s ...

  7. 关于MyBatis mapper的insert, update, delete返回值

    这里做了比较清晰的解释: http://mybatis.github.io/mybatis-3/java-api.html SqlSession As mentioned above, the Sql ...

  8. mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干

    1.mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干 2.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性).Con ...

  9. [Hive - LanguageManual] DML: Load, Insert, Update, Delete

    LanguageManual DML Hive Data Manipulation Language Hive Data Manipulation Language Loading files int ...

随机推荐

  1. 【译】如何高效的使用 Git

    原文链接 代码昨天还是运行好好的今天就不行了. 代码被删了. 突然出现了一个奇怪的 bug,但是没人知道怎么回事. 如果你出现过上面的任何一种情况,那本篇文章就是为你准备的. 除了知道 git add ...

  2. SignalR的Javascript客户端API使用方式整合

      PersistentConnection Hub/生成Proxy模式 Hub/非生成Proxy模式 服务端配置 app.Map("/messageConnection", ma ...

  3. Ocelot + Consul实践

    关于Consul(https://www.consul.io)是一个分布式,高可用,支持多数据中心的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla ...

  4. asp.net core系列 34 EF保存数据(1)

    一. 基本数据 每个EF上下文实例都有一个 ChangeTracker(更改跟踪器),它负责跟踪需要写入数据库的更改. 当更改实体类的实例时(修改属性,删除实例,新建实例等),这些更改会记录在 Cha ...

  5. Too many authentication failures for xxxx_username

    解释 这个报错通常是因为多个ssh key 验证,key太多了导致服务器拒绝接受认证请求. 可以通过 -v 参数,输出详细的过程.你会发现你提供的认证key,服务器拒绝链接,并提示异常:"T ...

  6. 带着新人学springboot的应用13(springboot+热部署)

    spring cloud我想做成一个系列,所以spring cloud+eureka后面会慢慢说到的,有兴趣的小伙伴可以关注后续! 这一节就简单说说springboot的热部署了(我一直想不通为什么叫 ...

  7. Django中的templates(你的HTML页面放哪里)

    本文回答Django里面的HTML文件应该怎么放,以及Django是如何查找模板文件的. 到目前为止我们没有使用HTML页面,在之前的说明中所有内容都是写死在程序里的,如果你想改变内容就要修改代码.但 ...

  8. yum仓库的创建

    这篇博客是yum仓库的配置过程,如果是yum客户端配置请参考 http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_linux_002.html 1 环境介 ...

  9. 常用API。

    object类: 1.equals方法: public boolean equals (Object obj) , 指示其他某个对象是否与此对象“相等” 源码:public boolean equal ...

  10. Java开发笔记(六十)匿名内部类的优势

    前面依次介绍了简单接口和扩展接口,给出的范例都是自定义的接口代码,其实Java系统本身就自带了若干行为接口,为了更好地理解系统接口的详细用法,接下来还是从一个基础的例子出发,抽丝剥茧地逐步说明接口的几 ...