在一个特定的SQL语句或会话中停用触发器

2016-02-19 19:35 5 1 收藏

今天图老师小编给大家介绍下在一个特定的SQL语句或会话中停用触发器,平时喜欢在一个特定的SQL语句或会话中停用触发器的朋友赶紧收藏起来吧!记得点赞哦~

【 tulaoshi.com - 编程语言 】

  问题

  我有一个创建在表上的触发器,当对表执行一个INSERT,DELETE或者UPDATE语句时,这个触发器将被激活执行。我想在一个特定的语句上阻止触发器被激活,而当执行其它语句时触发器仍然保持正常的执行状态。有没有一种方法可以动态做到这些?

  专家解答

  在某些时候,停用触发器是可能需要你去做的事情,尤其是你在一张表上执行管理员任务时。实现这点的最好方法是使用以下的命令去完全停用触发器。

  ALTER TABLE Table_Name DISABLE TRIGGER Trigger_Name

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  尽管如此,如果你只想在一个特殊的语句上停用触发器,然而没有一种默认的机制来实现这一点,除非你开发一种自己的可编程的方法。使用这种方法只在某个特定语句上停用触发器而这个触发器在其他同时点击服务器的语句上继续被激活执行。

  即使有很多种方式去实现它,主要的逻辑在于传递一些信号给触发器,告诉触发器你不需要激活它执行。

  使用一张临时表

  实现这个任务最简单的方法是在你执行会激活触发器的语句之前先创建一张临时表。现在这个触发器将检查临时表存在与否,并且,如果这张临时表存在,那么触发器将会返回并且不执行代码,否则它将会像平常一样执行它的代码。

  为了看看执行过程,让我们来运行以下的语句来创建一张表和一个触发器。

  USEAdventureWorks;
  GO
  --creatingthetableinAdventureWorksdatabase
  IFOBJECT_ID('dbo.Table1')ISNOTNULL
  DROPTABLEdbo.Table1
  GO
  CREATETABLEdbo.Table1(IDINT)
  GO
  --Creatingatrigger
  CREATETRIGGERTR_TestONdbo.Table1FORINSERT,UPDATE,DELETE
  AS
  IFOBJECT_ID('tempdb..#Disable')ISNOTNULLRETURN
  PRINT'TriggerExecuted'
  --Actualcodegoeshere
  --Forsimplicity,Ididnotincludeanycode
  GO

  如果你不想触发器在一个语句上被激活执行,那么通过在你的语句中创建临时表让触发器知道这一点。

  CREATETABLE#Disable(IDINT)
  --Actualstatement
  INSERTdbo.Table1VALUES(600)
  DROPTABLE#Disable

  你会发现INSERT语句并没有激活触发器,并且由于创建的临时表在本地会话中,触发器不能通过其他会话绕过。

  这个过程可能比较顺利,但是必须使用Tempdb数据库来创建一张临时表,接着删除这张临时表,这将导致资源浪费,不过这种情况是可以避免的。

  使用Context_Info( )

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  完成这个任务的另一种方法是使用会话中的上下文信息。上下文信息是属于某个会话的一个变量。它的值可以通过SET Context_Info更改。

  触发器看起来通常像这样:

  USEAdventureWorks;
  GO
  --creatingthetableinAdventureWorksdatabase
  IFOBJECT_ID('dbo.Table1')ISNOTNULL
  DROPTABLEdbo.Table1
  GO
  CREATETABLEdbo.Table1(IDINT)
  GO
  --Creatingatrigger
  CREATETRIGGERTR_TestONdbo.Table1FORINSERT,UPDATE,DELETE
  AS
  DECLARE@CinfoVARBINARY(128)
  SELECT@Cinfo=Context_Info()
  IF@Cinfo=0x55555
  RETURN
  PRINT'TriggerExecuted'
  --Actualcodegoeshere
  --Forsimplicity,Ididnotincludeanycode
  GO

  如果你想阻止触发器执行,那么你可以运行下面的代码:

  SETContext_Info0x55555
  INSERTdbo.Table1VALUES(100)

  执行INSERT语句之前,上下文信息设置成一个值。在这个触发器中,我们首先查看上下文信息的值与声明的值是否一样。如果是一样的,那么这个触发器将会仅做返回操作而不执行它的代码。要不然这个触发器将会被激活执行。

来源:http://www.tulaoshi.com/n/20160219/1621391.html

延伸阅读
如果你创建了一个登录触发器,并且在这个触发器中有一些不好的代码,那么当你尝试着登录时,你将会得到一个类似于图一显示的错误: 图一 如果不能很好地执行登录触发器,那么将会导致登录失败。 例如,如果创建了这个触发器,那么就可以设计下面的代码来达到失败的目的。 CREATE TRIGGER BadLogonTrigger ON ALL SER...
触发器是数据库应用中的重用工具,它的应用很广泛。这几天写一个化学数据统计方面的软件,需要根据采样,自动计算方差,在这里,我使用了触发器。 下面我摘录了SQL Server官方教程中的一段关于触发器的文字,确实有用的一点文字描述。 可以定义一个无论何时用INSERT语句向表中插入数据时都会执行的触发器。 当触发INSERT触发器时,新的...
这些年来,我发现许多开发者对于何时使用数据操纵语言(DML)触发器与何时使用约束感到迷惑。许多时候,如果没有正确应用这两个对象,就会造成问题。本文将为您何时使用约束和DML触发器提供一些启示,以帮助你避免我遇到的纠正问题。 何为约束和DML触发器? 约束是数据库引擎用来约束一个表或一个表关系中的数据,以维持数据库完...
错误如图所示: 图一 如果不能很好地执行登录触发器,那么将会导致登录失败。 例如,如果创建了这个触发器,那么就可以设计下面的代码来达到失败的目的。 代码如下: CREATE TRIGGER BadLogonTrigger ON ALL SERVER FOR LOGON AS BEGIN INSERT INTO BadDB.dbo.SomeTable VALUES ('Test'); END; GO 没有一个数据库称为BadDB,这...
标签: MySQL mysql数据库
Conventions and Styles约定和编程风格 每次我想要演示实际代码时,我会对mysql客户端的屏幕就出现的代码进行调整,将字体改成Courier,使他们看起来与普通文本不一样(让大家区别程序代码和正文)。在这里举个例子: mysql DROP FUNCTION f; Query OK, 0 rows affected (0.00 sec)...

经验教程

200

收藏

14
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部