SQLServer之修改触发器

修改触发器规则

修改CREATE TRIGGER语句之前建立的 DML、DDL 或登陆触发器的定义。触发器是经过使用CREATE TRIGGER建立的。这些触发器能够由Transact-SQL语句直接建立,也能够由程序集方法建立,这些方法在Microsoft .NET Framework公共语言运行时 (CLR)中建立并上传到SQL Server的实例。sql

DML 触发器

经过表和视图上的INSTEAD OF触发器,ALTER TRIGGER支持可手动更新的视图。SQL Server以相同的方式对全部类型的触发器(AFTER、INSTEAD-OF)应用ALTER TRIGGER。数据库

可使用sp_settriggerorder来指定要对表执行的第一个和最后一个AFTER触发器。 对一个表只能指定第一个和最后一个AFTER触发器。 若是在同一个表上还有其余AFTER触发器,这些触发器将随机执行。服务器

若是ALTER TRIGGER语句更改了第一个或最后一个触发器,将删除所修改触发器上设置的第一个或最后一个属性,而且必须使用sp_settriggerorder重置顺序值。架构

只有在成功执行触发SQL语句以后,才会执行AFTER触发器。 判断执行成功的标准是:执行了全部与已更新对象或已删除对象相关联的引用级联操做和约束检查。 AFTER 触发器操做要检查触发语句的效果,也包括全部由触发语句引发的 UPDATE 和 DELETE 引用级联操做。优化

若是一个子表或引用表上的 DELETE 操做是因为父表的 CASCADE DELETE 操做所引发的,而且子表上定义了 DELETE 的 INSTEAD OF 触发器,那么将忽略该触发器并执行 DELETE 操做。加密

DDL 触发器

与DML触发器不一样,DDL触发器的做用域不是架构。 所以,在查询有关DDL触发器的元数据时,不能使用OBJECT_ID、OBJECT_NAME、OBJECTPROPERTY 和 OBJECTPROPERTY(EX)。 请改用目录视图。 有关详细信息,请参阅获取有关 DDL 触发器的信息。spa

登陆触发器

Azure SQL Database 不支持针对登陆事件的触发器。代理

Permissions

若要更改DML触发器,须要对于定义该触发器所在的表或视图拥有 ALTER 权限。server

若要更改定义了服务器范围 (ON ALL SERVER) 的DDL触发器或者更改登陆触发器,须要对该服务器拥有CONTROL SERVER权限。 若要更改定义了数据库范围 (ON DATABASE) 的DDL触发器,须要对当前数据库拥有ALTER ANY DATABASE DDL TRIGGER权限。xml

触发器修改

语法:

--声明数据库引用
use 数据库;
go

--修改触发器
alter

--触发器标识符
trigger

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

on

--对其执行DML触发器的表或视图,有时称为触发器表或触发器视图。能够根据须要指定表或视图的彻底限定名称。视图只能被INSTEAD OF触发器引用。不能对局部或全局临时表定义DML触发器。

--DATABASE

--将 DDL 触发器的做用域应用于当前数据库。 若是指定了此参数,则只要当前数据库中出现 event_type 或 event_group,就会激发该触发器。

--ALL SERVER
--适用范围: SQL Server 2008 到 SQL Server 2017。

--将 DDL 或登陆触发器的做用域应用于当前服务器。 若是指定了此参数,则只要当前服务器中的任何位置出现 event_type 或 event_group,就会激发该触发器。

{ [架构名].表名| [架构名].视图 } { database| all server } { all server }

--with
--此属性适用于全部触发器类型
--加密包含ALTER TRIGGER语句文本的sys.syscomments和sys.sql_modules项。使用WITH ENCRYPTION能够防止将触发器做为SQL Server复制的一部分进行发布。不能为CLR触发器指定WITH ENCRYPTION。
--encryption,

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

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

--此属性适用于全部触发器类型
--{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
--CALLER
--指定模块内的语句在模块调用方的上下文中执行。 执行模块的用户不只必须对模块自己拥有适当的权限,还要对模块引用的任何数据库对象拥有适当权限。
--CALLER 是除队列外的全部模块的默认值,与 SQL Server 2005 行为相同。
--CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 语句中指定。
--SELF
--EXECUTE AS SELF 与 EXECUTE AS user_name 等价,其中指定用户是建立或更改模块的用户。 建立或更改模块的用户的实际用户 ID 存储在 sys.sql_modules 或 sys.service_queues 目录视图的 execute_as_principal_id 列中。
--SELF 是队列的默认值。
--OWNER
--指定模块内的语句在模块的当前全部者上下文中执行。 若是模块没有指定的全部者,则使用模块架构的全部者。 不能为 DDL 或登陆触发器指定 OWNER。
--' user_name '
--指定模块内的语句在 user_name 指定的用户的上下文中执行。 将根据 user_name 来验证对模块内任意对象的权限。 不能为具备服务器做用域的 DDL 触发器或登陆触发器指定 user_name。 请改用 login_name。
--user_name 必须存在于当前数据库中,而且必须是单一实例账户。 user_name 不能为组、角色、证书、密钥或内置账户,如 NT AUTHORITYLocalService、NT AUTHORITYNetworkService 或 NT AUTHORITYLocalSystem。
--执行上下文的用户 ID 存储在元数据中,能够在 sys.sql_modules 或 sys.assembly_modules 目录视图的 execute_as_principal_id 列查看。
--内存优化表上的触发器须要使用此选项。
--execute as { caller | self | owner | 'username'}

--FOR | AFTER
--AFTER 指定 DML 触发器仅在触发 SQL 语句中指定的全部操做都已成功执行时才被触发。 全部的引用级联操做和约束检查也必须在激发此触发器以前成功完成。
--若是仅指定 FOR 关键字,则 AFTER 为默认值。
--不能对视图定义 AFTER 触发器。

--INSTEAD OF

--指定执行 DML 触发器而不是触发 SQL 语句,所以,其优先级高于触发语句的操做。 不能为 DDL 或登陆触发器指定 INSTEAD OF。

--对于表或视图,每一个 INSERT、UPDATE 或 DELETE 语句最多可定义一个 INSTEAD OF 触发器。 可是,能够为具备本身的 INSTEAD OF 触发器的多个视图定义视图。

--不容许在使用 WITH CHECK OPTION 建立的视图上定义 INSTEAD OF 触发器。 将 INSTEAD OF 触发器添加到为其指定了 WITH CHECK OPTION 的视图时, SQL Server 将引起错误。 用户必须用 ALTER VIEW 删除该选项后才能定义 INSTEAD OF 触发器。

{ for | after | instead of }

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

--event_type

--执行以后将致使激发 DDL 触发器的 Transact-SQL 语言事件的名称。 DDL 事件中列出了 DDL 触发器的有效事件。

--event_group
--预约义的 Transact-SQL 语言事件分组的名称。 执行任何属于 event_group 的 Transact-SQL 语言事件以后,都将激发 DDL 触发器。 DDL 事件组中列出了 DDL 触发器的有效事件组。 ALTER TRIGGER 运行完成后,event_group 还将充当宏,将它涉及的事件类型添加到 sys.trigger_events 目录视图中。

{ [insert] [,] [update] [,] [delete] } { event_type [ ,...n ] | event_group }

--此属性应用于DML触发器的表和视图

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

as
begin

  sql_statement;

end;

示例:本示例演示修改DML插入触发器。

--声明数据库引用
use testss;
go

--修改触发器
alter

--触发器标识符
trigger

--DML触发器所属架构的名称。 DML触发器的做用域是为其建立该触发器的表或视图的架构。不能为DDL或登陆触发器指定
--dbo触发器名称
dbo.inserttri

on

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

with
--此属性适用于全部触发器类型
--加密包含ALTER TRIGGER语句文本的sys.syscomments和sys.sql_modules项。使用WITH ENCRYPTION能够防止将触发器做为SQL Server复制的一部分进行发布。不能为CLR触发器指定WITH ENCRYPTION。
--encryption,

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

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

--此属性适用于全部触发器类型
--{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
--CALLER
--指定模块内的语句在模块调用方的上下文中执行。 执行模块的用户不只必须对模块自己拥有适当的权限,还要对模块引用的任何数据库对象拥有适当权限。
--CALLER 是除队列外的全部模块的默认值,与 SQL Server 2005 行为相同。
--CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 语句中指定。
--SELF
--EXECUTE AS SELF 与 EXECUTE AS user_name 等价,其中指定用户是建立或更改模块的用户。 建立或更改模块的用户的实际用户 ID 存储在 sys.sql_modules 或 sys.service_queues 目录视图的 execute_as_principal_id 列中。
--SELF 是队列的默认值。
--OWNER
--指定模块内的语句在模块的当前全部者上下文中执行。 若是模块没有指定的全部者,则使用模块架构的全部者。 不能为 DDL 或登陆触发器指定 OWNER。
--' user_name '
--指定模块内的语句在 user_name 指定的用户的上下文中执行。 将根据 user_name 来验证对模块内任意对象的权限。 不能为具备服务器做用域的 DDL 触发器或登陆触发器指定 user_name。 请改用 login_name。
--user_name 必须存在于当前数据库中,而且必须是单一实例账户。 user_name 不能为组、角色、证书、密钥或内置账户,如 NT AUTHORITYLocalService、NT AUTHORITYNetworkService 或 NT AUTHORITYLocalSystem。
--执行上下文的用户 ID 存储在元数据中,能够在 sys.sql_modules 或 sys.assembly_modules 目录视图的 execute_as_principal_id 列查看。
--内存优化表上的触发器须要使用此选项。
execute as self

--FOR | AFTER
--AFTER 指定 DML 触发器仅在触发 SQL 语句中指定的全部操做都已成功执行时才被触发。 全部的引用级联操做和约束检查也必须在激发此触发器以前成功完成。
--若是仅指定 FOR 关键字,则 AFTER 为默认值。
--不能对视图定义 AFTER 触发器。
for

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

--此属性应用于DML触发器的表和视图
--指示当复制代理修改涉及到触发器的表时,不该执行触发器。
not for replication

as
begin
declare @sname nvarchar(100)=NULL,@sclassid int=NULL;
set @sname=(select name from inserted);
set @sclassid=(select classid from inserted);

--判断是否须要向test插入name
if @sname is not null
begin
if(select id from dbo.test2 where name=@sname) is null
begin
insert into dbo.test2(name) values(@sname);
end;
end;

--判断是否须要向test3插入classid
if @sclassid is not null
begin

if (select id from dbo.test3 where id=@sclassid) is not null
begin
print(@sclassid);
--insert into dbo.test1(name,sex,age,classid,height,xml1,xml2)
--select name,sex,age,classid,height,xml1,xml2 from inserted;
end;
end;
end;

示例结果:当向test1表中插入classid时,插入test3已存在的id时会打印1,插入test3不存在的id时不会打印1。

clipboard.png

clipboard.png

相关文章
相关标签/搜索