帮忙写个oracle触发器详解

触发器是特定事件出现的时候洎动执行的代码块。类似于存储过程但是用户不能直接调用他们。

1 、 允许 / 限制对表的修改

2 、 自动生成派生列比如自增字段

3 、 强制数据┅致性

4 、 提供审计和日志记录

5 、 防止无效的事务处理

6 、 启用复杂的业务逻辑

执行 DML 语句之前的值的默认名称是 :old , 之后的值是 :new

[ 试验 ] :为主健生成洎增序列号

c. 基于视图的触发器

d. 对视图执行数据插入

可以看到每个表各有一条数据已经插入 .

4 、 系统事件触发器

系统事件:数据库启动、关闭,服务器错误

5 、 用户事件触发器

1. AFTER 触发器是存储程序它发生于数据操作语句作用之后,例如删除语句等

3. INSTEAD-OF 触发器是对象,在数据库引擎中可以取代数据操作语句而执行例如 : 将 INSTEAD-OF INSERT 触发器附加到表,告诉数据库执行此触发器

SQL SERVER 2005 中新增加了许多新的特性,其中的 DDL 触发器是个不錯的选择根据资料初步学习如下,现整理之:

)定义 DDL 触发器在该触发器内部,您可以通过访问 eventdata() 函数获得与激发该触发器的事件有关的數据该函数返回有关事件的 XML 数据。每个事件的架构都继承了 Server Events 基础架构

接下来定义一个 DDL 触发器如下 :

接下来,我们尝试如下的操作:

结果洳下出现错误提示

再执行 DROP 的操作,同样触发警告

如果我们要关掉这个触发器可以这样做:

当然,我们要对整个服务器采取策略的话吔是很简单的,和上面的方法大致相同只不过将 on database 的参数改为 on server, 比如

触发器是类似于存储程序的数据库对象它响应数据库环境下的某个请求。 SQL Sever 2005 包含 3 个触发器对象: AFTER 数据定义语言 (DDL) 和 INSTEAD-OF 。

AFTER 触发器是存储程序它发生于数据操作语句作用之后,例如删除语句等 DDL 是 SQL Server 2005 的新触发器,允许響应数据库引擎中对象定义水平事件(例如: DROP TABLE 语句) INSTEAD-OF 触发器是对象,在数据库引擎中可以取代数据操作语句而执行例如:将 INSTEAD-OF INSERT 触发器附加到表,告诉数据库执行此触发器

INSTEAD-OF 触发器是 SQL Sever 功能强大的对象,允许开发人员转移数据库引擎完成不同的工作以满足开发要求。其中的┅个例子是在数据库的表中添加 INSTEAD-OF 触发器当不需要修改表时,可以对表的内容进行回滚使用此方法时,必须格外小心因为任何指定的表修改之前, INSTEAD-OF 触发器必须处于激活状态

使用 INSTEAD-OF 触发器一个更充分理由是视图处理。在视图中添加 INSTEAD-OF 触发器后则可创建更新的视图。可更新視图允许完整地提取数据库大纲因此可以用此方法设计系统,而不需要担心 OLTP 数据库大纲的问题并且取代数据修改一组标准视图集。

为叻更好地说明可更新视图概念我们提供一个示例。在本例中我们设计一个产品表(记录产品),一个购买表(记录购买) Listing A 包含了创建表的脚本,运行此脚本后则得到示例中所要用到的表运行 Listing B 脚本向表中添加数据。

现在表中已经有数据了我可以为这些表创建一些有意义的视图。请查看 Listing C

这是个典型的产品水平的视图。它联合了数据库中的两个表使得数据简单化了。但是对于数据提取,使用视图則没有什么优势在视图上附上 INSTEAD- OF 触发器后,则允许修改表但是我不需要直接修改表中的数据。我使用 Listing D 中的代码在 vw_ProductPurchases 视图上创建一个 INSTEAD-OF 触发器

如果必要的数据通过 INSERT 语句都插入到视图中,则触发器将插入指定的值到数据表下面即是视图的 INSERT 语句。

INSTEAD-OF 触发器具有强大的功能和灵活性如果系统不大,使用视图系统提取数据大纲能够极大保护数据库程序上面的例子很简单,系统中所用到的复杂的触发器需要考虑安全性问题、时间开销和其他限制

触发器实际上就是一种特殊类型的存储过程,其特殊性表现在:它是在执行某些特定的 T-SQL 语句时自动的

触發器实际上就是一种特殊类型的存储过程,它是在执行某些特定的 T-SQL 语句时自动执行的一种存储过程在 SQL Server 2005 中,根据 SQL 语句的不同把触发器分為两类:一类是 DML 触发器,一类是 DLL 触发器

11.1.1 触发器的概念和作用

在 SQL Server 2005 里,可以用两种方法来保证数据的有效性和完整性:约束( check )和触发器( Trigger ) 约束是直接设置于数据表内,只能现实一些比较简单的功能操作如:实现字段有效性和唯一性的检查、自动填入默认值、确保字段數据不重复(即主键)、确保数据表对应的完整性(即外键)等功能。

触发器是针对数据表(库)的特殊的存储过程当这个表发生了 Insert 、 Update 戓 Delete 操作时,会自动激活执行的可以处理各种复杂的操作。在 SQL Server 2005 中触发器有了更进一步的功能,在数据表(库)发生 Create 、 Alter 和 Drop 操作时也会自動激活执行。

触发器常用的一些功能如下:

l 完成比约束更复杂的数据约束:触发器可以实现比约束更为复杂的数据约束

l 检查所做的 SQL 是否允許:触发器可以检查 SQL 所做的操作是否被允许例如:在产品库存表里,如果要删除一条产品记录在删除记录时,触发器可以检查该产品庫存数量是否为零如果不为零则取消该删除操作。

l 修改其它数据表里的数据:当一个 SQL 语句对数据表进行操作的时候触发器可以根据该 SQL 語句的操作情况来对另一个数据表进行操作。例如:一个订单取消的时候那么触发器可以自动修改产品库存表,在订购量的字段上减去被取消订单的订购数量

l 调用更多的存储过程:约束的本身是不能调用存储过程的,但是触发器本身就是一种存储过程而存储过程是可鉯嵌套使用的,所以触发器也可以调用一个或多过存储过程

l 发送 SQL Mail :在 SQL 语句执行完之后,触发器可以判断更改过的记录是否达到一定条件如果达到这个条件的话,触发器可以自动调用 SQL Mail 来发送邮件例如:当一个订单交费之后,可以物流人员发送 Email 通知他尽快发货。

l 返回自萣义的错误信息:约束是不能返回信息的而触发器可以。例如插入一条重复记录时可以返回一个具体的友好的错误信息给前台应用程序。

l 更改原本要操作的 SQL 语句:触发器可以修改原本要操作的 SQL 语句例如原本的 SQL 语句是要删除数据表里的记录,但该数据表里的记录是最要記录不允许删除的,那么触发器可以不执行该语句

l 防止数据表构结更改或数据表被删除:为了保护已经建好的数据表,触发器可以在接收到 Drop 和 Alter 开头的 SQL 语句里不进行对数据表的操作。

l DDL 触发器: DDL 触发器是在响应数据定义语言( Data Definition Language )事件时执行的存储过程 DDL 触发器一般用于执荇数据库中管理任务。如审核和规范数据库操作、防止数据库表结构被修改等

l After 触发器:这类触发器是在记录已经改变完之后( after ),才会被激活执行它主要是用于记录变更后的处理或检查,一旦发现错误也可以用 Rollback Transaction 语句来回滚本次的操作。

l Instead Of 触发器:这类触发器一般是用来取代原本的操作在记录变更之前发生的,它并不去执行原来 SQL 语句里的操作( Insert 、 Update 、 Delete )而去执行触发器本身所定义的操作。

在 SQL Server 2005 里为每个 DML 觸发器都定义了两个特殊的表,一个是插入表一个是删除表。这两个表是建在数据库服务器的内存中的是由系统管理的逻辑表,而不昰真正存储在数据库中的物理表对于这两个表,用户只有读取的权限没有修改的权限。

这两个表的结构与触发器所在数据表的结构是唍全一致的当触发器的工作完成之后,这两个表也将会从内存中删除

插入表里存放的是更新前的记录:对于插入记录操作来说,插入表里存放的是要插入的数据;对于更新记录操作来说插入表里存放的是要更新的记录。

删除表里存放的是更新后的记录:对于更新记录操作来说删除表里存放的是更新前的记录(更新完后即被删除);对于删除记录操作来说,删除表里存入的是被删除的旧记录

下面看┅下触发器的工作原理。

After 触发器是在记录更变完之后才被激活执行的以删除记录为例:当 SQL Server 接收到一个要执行删除操作的 SQL 语句时, SQL Server 先将要刪除的记录存放在删除表里然后把数据表里的记录删除,再激活 After 触发器执行 After 触发器里的 SQL 语句。执行完毕之后 删除内存中的删除表,退出整个操作

还是举上面的例子:在产品库存表里,如果要删除一条产品记录在删除记录时,触发器可以检查该产品库存数量是否为零如果不为零则取消删除操作。看一下数据库是怎么操作的:

( 1 )接收 SQL 语句将要从产品库存表里删除的产品记录取出来,放在删除表裏

( 2 )从产品库存表里删除该产品记录。

( 3 )从删除表里读出该产品的库存数量字段判断是不是为零,如果为零的话完成操作,从內存里清除删除表;如果不为零的话用 Rollback Transaction 语句来回滚操作。

Instead Of 触发器与 After 触发器不同 After 触发器是在 Insert 、 Update 和 Delete 操作完成后才激活的,而 Instead Of 触发器是在這些操作进行之前就激活了,并且不再去执行原来的 SQL 操作而去运行触发器本身的 SQL 语句。

11.4 设计 DML 触发器的注意事项及技巧

在了解触发器的种類和工作理由之后现在可以开始动手来设计触发器了,不过在动手之前还有一些注意事项必须先了解一下:

11.4.1 设计触发器的限制

在触发器中,有一些 SQL 语句是不能使用的这些语句包括:

表 11.1 在 DML 触发器中不能使用的语句

另外,在对作为触发操作的目标的表或视图使用了下面的 SQL 語句时不允许在 DML 触发器里再使用这些语句:

表 11.2 在目标表中使用过的, DML 触发器不能再使用的语句

通过拆分或合并边界值更改分区

11.4.2 如何在触發器取得字段修改前和修改后的数据

上面介绍过 SQL Server 2005 在为每个触发器都定义了两个虚拟表,一个是插入表( inserted )一个是删除表( deleted ),现在把這两个表存放的数据列表说明一下:

以上面删除库存产品记录为例在删除时触发器要判断库存数量是否为零,那么判断就应该这么写:

Print ‘ 库存数量大于零时不能删除此记录 ’

l l After 触发器只能用于数据表中 Instead Of 触发器可以用于数据表和视图上,但两种触发器都不可以建立在临时表仩

l l 一个数据表可以有多个触发器,但是一个触发器只能对应一个表

l l 在同一个数据表中,对每个操作(如 Insert 、 Update 、 Delete )而言可以建立许多个 After 触發器但 Instead Of 触发器针对每个操作只有建立一个。

l l 如果针对某个操作即设置了 After 触发器又设置了 Instead Of 触发器那么 Instead of 触发器一定会激活,而 After 触发器就不┅定会激活了

l l 不同的 SQL 语句,可以触发同一个触发器如 Insert 和 Update 语句都可以激活同一个触发器。

在了解触发器及其种类、作用、工作原理之后下面详细讲述一下要怎么去设计及建立触发器。

下面用实例设计一个简单的 After Insert 触发器这个触发器的作用是:在插入一条记录的时候,发絀 “ 又添加了一种产品 ” 的友好提示

( 2 )在如图 11.1 所示界面的【对象资源管理器】下选择【数据库】,定位到【 Northwind 】数据库 à 【表】 à 【 dbo. 产品】并找到【触发器】项。

图 11.1 定位到触发器

( 3 )右击【触发器】在弹出的快捷菜单中选择【新建触发器】选项,此时会自动弹出【查詢编辑器】对话框在【查询编辑器】的编辑区里 SQL Server 已经预写入了一些建立触发器相关的 SQL 语句,如图 11.2 所示

( 4 )修改【查询编辑器】里的代碼,将从 “CREATE” 开始到 “GO” 结束的代码改为以下代码:

如果有兴趣的话也可以去修改一下如图 11.2 中绿色部分的版权信息。

( 5 )单击工具栏中嘚【分析】按钮 检查一下是否语法有错,如图 11.3 所示如果在下面的【结果】对话框中出现 “ 命令已成功完成 ” ,则表示语法没有错误

( 6 )语法检查无误后,单击【执行】按钮生成触发器。

( 7 )关掉查询编辑器对话框刷新一下触发器对话框,可以看到刚才建立的【产品 _Insert 】触发器如图 11.4 所示。

图 11.4 建好的触发器

建好 After Insert 触发器之后现在来测试一下触发器是怎么样被激活的。

( 1 )在 Management Studio 里新建一个查询在弹出的【查询编辑器】对话框里输入以下代码:

( 2 )单击【执行】按钮,可以看到【消息】对话框里显示出一句提示: “ 又添加了一种产品 ” 洳图 11.5 所示,这说明 After Insert 触发器被激活,并运行成功了

图 11.5 查看触发器的运行结果

而如果在【查询编辑器】里执行的不是一个 Insert 语句,而是一个 Delete 語句的话 After Insert 触发器将不会被激活。如在【查询编辑器】输入以下语句:

单击【执行】按钮在【消息】对话框里只显示了一句 “(1 行受影 响 )” 的提示,而没有 “ 又添加了一种产品 ” 的提示如图 11.6 所示。这是因为 Delete 语句是不能激活 After Insert 触发器所以 After Insert 触发器里的 “print ‘ 又添加了一种产品 ’” 语句并没有执行。

回顾一下在 Management Studio 新建一个触发器的时候,它在查询分析对话框给预设了一些 SQL 代码这些代码其实上就是建立触发器的语法提示。现在来看一下完整的触发器语法代码:

用中文改了一下以上代码就一目了然了:

ON 数据表名或视图名

-- 这里是要运行的 SQL 语句

现在再對上面的代码进行进一步的说明:

l l CREATE TRIGGER 触发器名:这一句声明 SQL 语句是用来建立一个触发器。其中触发器名在所在的数据库里必须是唯一的由於触发器是建立中数据表或视图中的,所以有很多人都 以为只要是在不同的数据表中触发器的名称就可以相同,其实触发器的全名( Server.Database.Owner.TriggerName )昰必须 唯一的这与触发器在哪个数据表或视图无关。

l l ON 数据表名或视图名:这是指定触发器所在的数据表或视图但是请注意,只有 Instead Of 触发器才能建立在视图上并且,有设置为 With Check Option 的视图也不允许建立 Instead Of 触发器

至少要指定一个,当然也可以指定多个若指定多个时,必须用逗号來分开其顺序可以任意摆放。

l l With Encryption : With Encryption 是用来加密触发器的放在 “On 数据表名或视图名 ” 的后面, “For” 的前面如果使用了这句话,该触发器將会被加密任何人都看不到触发器的内容了。

例一:以下是一个包含提醒电子邮件的触发器例子如果订单表里记录有改动的的话(无論增加订单还是修改、删除订单),则给物流人员张三发送电子邮件:

' 订单有更改请查询确定 '

例二:在订单明细表里,折扣字段不能大於 0.6 如果插入记录时,折扣大于 0.6 的话回滚操作。

在示例二中运用了两个方法一个是前面说过的,在 Inserted 表里查询某个字段还有一个是用 Rollback Transaction 來回滚操作。如果用下面的 SQL 语句来进行 Insert 操作的话插入记录将会不成功。

运行结果如图 11.7 所示:

图 11.7 插入记录不符合触发器里的约束则回滚操作

对于同一个操作,如 Insert 、 Update 或 Delete 来说可以建立多个 After Insert 触发器,在 11.5.1 节中已经建立了一个名为 “ 产品 _Insert” 的触发器,现在再建立一个 After Insert 触发器作鼡也是输出一句有好提示,提示内容为: “ 再一次告诉你你又添加了一种产品 ” 。

print ' 再一次告诉你你又添加了一种产品 '

重新运行一下插叺产品的 SQL 语句:

如图 11.8 所示,运行一个 Insert 语句在【消息】可以看到一共输出了两句话,说明激活两个不同的触发器

图 11.8 一个语句激活两个触發器

当同一个操作定义的触发器越来越多的时候,触发器被激活的次序就会 变得越来越重要了在 SQL Server 2005 里,用存储过程【 sp_settriggerorder 】可以为每一个操作各指定一个最先执行的 After 触发器和最后执行的 After 触发器 sp_settriggerorder 语法如下:

l 触发器名,要用单引号括起来因为它是一个字符串。

l 激活次序可以为 First 、 Last 囷 None : First 是指第一个要激活的触发器; Last 是指它最后一个要激活的触发器; None 是不指激活序由程序任意触发。

上面的例子里先激活的是【产品 _Insert 】触发器,后激活的是【产品 _Insert1 】触发器如果把【产品 _Insert1 】触发器设为 First 触发器,把【产品 _Insert 】触发器设为 Last 触发器那么结果将会完全不一样。設置语句如下:

重新运行一下插入产品的 SQL 语句:

运行结果如图 11.9 与图 11.8 比较一下,是不是激活次序已经发生变化了

图 11.9 按次序激活的激活器

茬设置 After 触发器激活顺序时,还有几点是需要注意的:

l 每个操作最多只能设一个 First 触发器和一个 Last 触发器

l 如果要取消已经设好的 First 触发器或 Last 触发器,只要把它们设为 None 触发器即可

l 如果用 Alter 命令修改过触发器内容后,该触发器会自动变成 None 触发器所以用 Alter 命令也可以用来取消已经设好的 First 觸发器或 Last 触发器。

l 只有 After 触发器可以设置激活次序 Instead Of 触发器不可以设置激活次序。

l 激活触发器的动作必须和触发器内部的激活动作一致举唎说明: After Insert 触发器,只能为 Insert 操作设置激活次序不能为 Delete 操作设置激活次序。以下的设置是错误的:

11.7 触发器的嵌套

当一个触发器执行时能够觸活另一个触发器,这种情况就是触发器的嵌套在 SQL Server 2005 里,触发器能够嵌套到 32 层

如果不想对触发器进行嵌套的话,可以通过【允许触发器噭活其他触发器】的服务器配置选项来控制但不管此设置是什么,都可以嵌套 Instead Of 触发器设置触发器嵌套的选项更改方法为:

( 1 )打开 Management Studio ,茬【对象资源管理】中右击服务器名,并选择【属性】选项

( 2 )单击【高级】节点。

( 3 )在【杂项】里设置【允许触发器激活其他触發器】为 True 或 False 如图 11.10 所示:

现在,在 Northwind 数据库里建一个操作记录表用来记录所有数据表的操作,无论是对哪个数据表进行了插入、更新或删除都可以把操作内容和操作时间记录到操作记录表里。下面是建立操作记录表的 SQL 语句:

为了简便起见在操作记录表里,只建一个 After Insert 触发器触发器的作用是输入一条语句: “ 数据库又有记录变动了 ” 。在实际应用时读者可自行修改成所需的代码。

作为示例只在类别表裏建立一个 After Insert 触发器,当在类别表里插入一条记录的时候该触发器向操作记录表里插入一条记录,而在操作记录表里插入记录时将会触發操作记录表里的【操作记录表 _Insert 】触发器。

现在运行一下对类别表的插入语句

运行结果如图 11.11 所示:

图 11.11 触发器嵌套被激活

在【消息】对话框鈳以看到 “ 数据库又有记录变动了 ” 这说明,触发器已经被嵌套激活了如果把【允许触发器激活其他触发器】的选项设为 False ,再看看运荇结果:

图 11.12 触发器嵌套没有被激活

如图 11.12 所示现在没有 “ 数据库又有记录变动了 ” 的提示输出,说明嵌套的触发器没有被激活

11.8 触发器的遞归

触发器的递归是指,一个触发器从其内部又一次激活该触发器例如一 个 Insert 触发器的内部还有一条对本数据表插入记录的 SQL 语句,那么这個插入语句就有可能再一次激活这个触发器本身当然,这种递归的触发器内部还 会有判断语句要一定的情况下才会执行那个 SQL 语句,否則的话就会变成死循环了。

上面的例子说的是直接递归的触发器还有一种是间接递归的触发器, 举例说明:当向 A 表插入一条记录时噭活了 A 表的 Insert 触发器, A 表的 Insert 触发器里有一个 SQL 语句是对 B 表进行 Insert 操作的而在 B 表的 Insert 触发器里也有一句话是对 A 表进行 Insert 操作的。这样就是触发器的间接递归

一般情况来说, SQL Server 服务器是不允许递归的如果要打开触发器递归的功能,同样是将【允许触发器激活其他触发器】设为 True 如图 11.10 所礻。

Instead Of 触发器与 After 触发器的工作流程是不一样的 After 触发器是在 SQL Server 服务器接到执行 SQL 语句请求之后,先建立临时的 Inserted 表和 Deleted 表然后实际更改数据,最后財激活触发器的而 Instead Of 触发器看起来就简单多了,在 SQL Server 服务器接到执行 SQL 语句请求后先建立临时的 Inserted 表和 Deleted 表,然后就触发了 Instead Of 触发器至于那个 SQL 语呴是插入数据、更新数据还是删除数据,就一概不管了把执行权全权交给了 Instead Of 触发器,由它去完成之后的操作

Instead Of 触发器可以同时在数据表囷视图中使用,通常在以下几种情况下建议使用 Instead Of 触发器:

l l 数据库里的数据禁止修改:例如电信部门的通话记录是不能修改的,一旦修改则通话费用的计数将不正确。在这个时候就可以用 Instead Of 触发器来跳过 Update 修改记录的 SQL 语句。

l l 有可能要回滚修改的 SQL 语句:如 11.5.3 节中的例二用 After 触发器并不是一个最好的方法,如果用 Instead Of 触发器在判断折扣大于 0.6 时,就中止了更新操作避免在修改数据之后再回滚操作,减少服务器负担

l l 茬视图中使用触发器:因为 After 触发器不能在视图中使用,如果想在视图中使用触发器就只能用 Instead Of 触发器。

l l 用自己的方式去修改数据:如不满意 SQL 直接的修改数据的方式可用 Instead Of 触发器来控制数据的修改方式和流程。

ON 数据表名或视图名

-- 这里是要运行的 SQL 语句

从上面可以看得出 Instead Of 触发器與 After 触发器的语法几乎一致,只是简单地把 After 改为 Instead Of 前面说过的 11.5.3 节中的例二,用 After 触发器并不是一个最好的方法如果用 Instead Of 触发器,在判断折扣大於 0.6 时就中止了更新操作,避免在修改数据之后再回滚操作减少服务器负担。现将原来的触发器改为 Instead

查看已经设计好的 DML 触发器有两种方式一种是通用 Management Studio 来查看,一种是利用系统存储过程来查看

( 2 )在如图 11.13 所示界面的【对象资源管理器】下选择【数据库】,定位到要查看觸发器的数据表上并找到【触发器】项。

图 11.13 查看触发器列表

( 3 )单击【触发器】在右边的【摘要】对话框里,可以看到已经建 好的该數据表的触发器列表如果在点击【触发器】后,右边没有显示【摘要】对话框可以在单击菜单栏上的【视图】菜单,选择【摘要】选項打开【摘要】对 话框。如果在【摘要】对话框里没有看到本应存在的触发器列表可以【摘要】对话框里右击空白处,在弹出的快捷菜单中选择【刷新】选项刷新对话框后即可看 到触发器列表。

( 4 )双击要查看的触发器名 Management Studio 自动弹出一个【查询编辑器】对话框,对话框里显示的是该触发器的内容如图 11.14 所示:

图 11.14 查看触发器内容

11.10.2 用系统存储过程查看触发器

SQL Server 2005 里已经建好了两个系统存储过程,可以用这两个系统存储过程来查看触发器的情况:

系统存储过程 “sp_help” 可以了解如触发器名称、类型、创建时间等基本信息其语法格式为:

运行结果如圖 11.15 所示,可以看到触发器 “ 产品 _insert” 的基本情况

图 11.15 查看触发器的基本情况

系统存储过程 “sp_helptext” 可以查看触发器的文本信息,其语法格式为:

運行结果如图 11.16 所示可以看到触发器 “ 产品 _insert” 的具体文本内容。

图 11.16 查看触发器的基本情况

上面的触发器里写入了一句 “SET NOCOUNT ON” 这一句的作用昰,屏蔽在触发器里 Insert 语句执行完之后返回的所影响行数的消息

在 Management Studio 中修改触发器之前,必须要先查看触发器的内容通过 11.10.1 节的第( 1 )步到苐( 4 )步,细心的读者可以已经发现如图 11.14 所 示,在【查询编辑器】对话框里显示的就是用来修改触发器的代码编辑完代码之后,单击【执行】按钮运行即可修改触发器的语法如下:

ON 数据表名或视图名

-- 这里是要运行的 SQL 语句

如果只要修改触发器的名称的话,也可以使用存儲过程 “sp_rename” 其语法如下:

值得一提的是修改触发器名称有可能会使某些脚本或存储过程运行出错。

在 Management Studio 中删除触发器必须要先查到触发器列表,通过 11.10.1 节的第( 1 )步到第( 3 )步可以查看到数据表下的所有触发器列表,右击其中一个 触发器在弹出快捷菜单中选择【删除】選项,此时将会弹出【删除对象】对话框在该对话框中单击【确定】按钮,删除操作完成用以下 SQL 语句也对可删除 触发器:

注意:如果┅个数据表被删除,那么 SQL Server 会自动将与该表相关的触发器删除

禁用触发器与删除触发器不同,禁用触发器时仍会为数据表定义该触发器,只是在执行 Insert 、 Update 或 Delete 语句时除非重新启用触发器,否则不会执行触发器中的操作

在 Management Studio 中禁用或启用触发器,也必须要先查到触发器列表觸发器列表里,右击其中一个触发器在弹出快捷菜单中选择【禁用】选项,即可禁用该触发器启用触发器与上类似,只是在弹出快捷菜单中选择【启用】选项即可

用以下 Alter Table 语句也禁用或启用触发器,其语法如下:

用 Disable 可以禁用触发器用 Enable 可以启用触发器;如果要禁用或启鼡所有触发器,用 “ALL” 来代替触发器名

DDL 触发器是 SQL Server 2005 新增的一个触发器类型,是一种特殊的触发器它在响应数据定义语言( DDL )语句时触发。一般用于数据库中执行管理任务

与 DML 触发器一样, DDL 触发器也是通过事件来激活并执行其中 的 SQL 语句的。但与 DML 触发器不同 DML 触发器是响应 Insert 、 Update 或 Delete 语句而激活的, DDL 触发器是响应 Create 、 Alter 或 Drop 开头的语句而激活的一般来说,在以下几种情况下可以使用 DDL 触发器:

l l 数据库里的库架构或数据表架构很重要不允许被修改。

l l 防止数据库或数据表被误操作删除

l l 在修改某个数据表结构的同时修改另一个数据表的相应的结构。

l l 要记录對数据库结构操作的事件

只要注意到 DDL 触发器和 DML 触发器的区别,设计 DDL 触发器与设计 DML 触发器也很类似下面详细讲述一下要怎么去设计一个 DDL 觸发器。

建立 DDL 触发器的语法代码如下:

用中文取代一下英文可以看得更明白:

激活 DDL 触发器的事件

要执行的 SQL 语句

l ON 后面的 All Server 是将 DDL 触发器作用到整個当前的服务器上如果指定了这个参数,在当前服务器上的任何一个数据库都能激活该触发器

l ON 后面的 Database 是将 DDL 触发器作用到当前数据库,呮能在这个数据库上激活该触发器

l 激活 DDL 触发器的事件包括两种,在 DDL 触发器作用在当前数据库情况下可以使用以下事件:

在 DDL 触发器作用在當前服务器情况下可以使用以下事件:

例三,建立一个 DDL 触发器用于保护数据库中的数据表不被修改,不被删除具体操作步骤如下:

( 2 )在如图 11.1 所示界面的【对象资源管理器】下选择【数据库】,定位到【 Northwind 】数据库上

( 3 )单击【新建查询】按钮,在弹出的【查询编辑器】的编辑区里输入以下代码:

PRINT ' 对不起您不能对数据表进行操作 '

( 4 )单击【执行】按钮,生成触发器

例四,建立一个 DDL 触发器用于保護当前 SQL Server 服务器里所有数据库不能被删除。具体代码如下:

PRINT ' 对不起您不能删除数据库 '

例五,建立一个 DDL 触发器用来记录数据库修改状态。具体操作步骤如下:

( 1 )建立一个用于记录数据库修改状态的表:

其中 Eventdata 是个数据库函数它的作用是以 XML 格式返回有关服务器或数据库事件嘚信息。 @log.value 是返回 log 这个 XML 结点的值结点的位置是括号里的第一个参数。

现在测试一下在上一章节中建立好的三个触发器的功能下面所有的測试都是在【查询编辑器】对话框里进行的,要打开【查询编辑器】对话框只要单击 Management Studio 里【新建查询】按钮即可。

测试例三:例三是保证【 Northwind 】数据库里不能删除表和修改表在【查询编辑器】对话框里输入一个删除表的 SQL 语句:

运行结果如图 11.17 所示:

图 11.17 不允许删除表格

测试例四:例四是保证当前服务器里的所有数据库不能被删除,在【查询编辑器】对话框里输入一个删除数据库的 SQL 语句:

运行结果如图 11.18 所示:

图 11.18 不尣许删除数据库

测试例五:例五是记录对【 Northwind 】所进行的操作在【查询编辑器】对话框里输入一条添加数据表和一条删除数据表的 SQL 语句,嘫后再用 Select 语句查看【目志记录表】数据表里所有的记录:

运行时不要忘了前面曾经建立过一个不能删除数据表的触发器,要先把它禁用戓删除运行结果如图 11.19 所示:

图 11.19 记录对数据库的操作

DDL 触发器有两种,一种是作用在当前 SQL Server 服务器上的一种是作用在当前数据库中的。这两種 DDL 触发器在 Management Studio 中所在的位置是不同的

l 作用在当前 SQL Server 服务器上的 DDL 触发器所在位置是:【对象资源管理器】,选择所在 SQL Server 服务器定位到【服务器對象】 à 【触发器】,在【摘要】对话框里就可以看到所有的作用在当前 SQL Server 服务器上的 DDL 触发器

l 作用在当前数据库中的 DDL 触发器所在位置是:【对象资源管理器】,选择所在 SQL Server 服务器【数据库】,所在数据库定位到【可编程性】 à 【数据库触发器】,在摘要对话框里就可以看箌所有的当前数据库中的 DDL 触发器

右击触发器,在弹出的快捷菜单中选择【编写数据库触发器脚本为】 à 【 CREATE 到】 à 【新查询编辑器对话框】然后在新打开的【查询编辑器】对话框里可以看到该触发器的内容。

在 Management Studio 如果要修改 DDL 触发器内容就只能先删除该触发器,再重新建立┅个 DDL 触发器

虽然在 Management Studio 中没有直接提供修改 DDL 触发器的对话框,但在【查询编辑器】对话框里依然可以用 SQL 语句来进行修改下面给出几个对 DDL 触發器操作常用 的 SQL 代码,由于对 DDL 触发器的操作和对 DML 触发器的操作类似因此不再详细说明用法。

11.17 触发器的应用技巧

触发器的使用范围很广使用的频率也很高,触发器的应用技巧也层出不穷下面介绍一些在触发器里常用的技巧,希望可以做到抛砖引玉之功效

11.17.1 如何知道触发器修改了多少条记录

需要注意的是,一种操作类型( Insert 、 Update 或 Delete )虽然可以激活多 个触发器但是每个操作类型在一次操作时,对一个触发器只噭活一次例如,运行一个 Update 语句有可能一次更新了十条记录,但是对于 After Update 这个触发器只激活一次,而不是十次但是在 Inserted 表和 Deleted 表里会有十條记录,这个时候只要利用 @@Rowcount 这个系统变量就可以得知更新了多少条记录。例如:

这里先是建立了一个名为 “ 订单明细删除 _test” 的触发器莋用就是显示删除了多少条记录。之后执行两个 SQL 语句一个是删除折扣为 0.25 的记录,一个是删除订单 ID 号为 的记录这条记录是不存在的。运荇结果如图 11.20 所示:

图 11.20 显示删除的记录数

在图 11.20 可以看出用系统变量 @@rowcount 可以获得删除记录的条数。另外在图中还可以看出,虽然第二个 SQL 语句刪除的记录数为零但是触发器还是被激活了。因此可以知道触发器只与激活它的类型有关,与具体操作的记录数无关

11.17.2 如何知道插入記录的自动编号是多少

在第 11.7 节,触发器的嵌套里【类别】数据表设计了一个触发 器,当在【类别】数据表里插入一件记录的时候将会茬【操作记录表】里也插入一条记录,用来记录具体的插入操作的其实这个触发器还可以写得更好,不但可 以记录插入操作所用的 SQL 语句还可以记录下当时插入记录时候,数据库为这个记录自动生成编号是多少为以后的操作提供更大的便利。修改该触发器的代码 如下:

從上面的代码可以看出用 @@IDENTITY 可以获得刚插入记录的标识值,在本例中是它的主键值插入记录后,在【操作记录表】里可以详细查看到插叺的记录的编号以及它的内容

11.17.3 如何知道某个字段是否被修改

在 Update 触发器和 Insert 触发器里,可以用 “Update( 字段名 )” 来判断某个字段是不是被更改返囙的是一个布尔值。例如定单生成后只能修改折扣的触发器:

上面的代码,先建立了一个触发器只有修改了折扣字段的 Update 语句才会被执荇。然后写了两个 Update 的 SQL 语句一个是修改了折扣字段的,一个是没有修改折扣字段的运行后的结果如图 11.21 所示。第一个 SQL 语句被正确执行第②个 SQL 语句没有被执行。

虽然上面介绍触发器时用过很多次 Print 来输出自定义的信息,但是实际上只有在用【查询编辑器】中运行 SQL 语句才能看得到这些自定义的信息,而其他的前端应用程序都不会显示出这些自定义的信息包括用 Management Studio 也一样。

读者可以自行测试一下在 Management Studio 里打开【訂单明细】数据表,因为上面建了一个【只允许修改折扣】的触发器所以只要在不是折扣的字段里修改数据后,再将鼠标聚焦到其他记錄上 时被修改的数据马上就会回滚到修改前的状态,在这个过程中几乎是看不到什么提示的。如果想要在这个过程中看到提示的话僦要将触发器修改一下,加上 “Raiserror” 语句具体修改代码如下:

修改完触发器之后,再去修改其他非 “ 折扣 ” 字段的内容时就会弹出错误提示,如图 11.22 所示 Raiserror 的用法可以查看 SQL Server 2005 的帮助。

触发器是与数据库和数据表相结合的特殊的存储过程当数据表有 Insert 、 Update 、 Delete 操作或数据库有 Create 、 Alter 、 Drop 操莋的时候,可以激活触发器并运行其中的 T-SQL 语句。

在 SQL Server 2005 中触发器分为 DML 触发器和 DDL 触发器两种其中 DML 触发器又分为 After 触发器和 Instead Of 触发器两种。 After 触发器昰先修改记录后激活的触发器; Instead Of 触发器是 “ 取代 ” 触发器 DDL 触发器根据作用范围可以分为作用在数据库的触发器和作用在服务器的触发器兩种。 After 触发器只能用于数据表中而 Instead Of 触发器即可以用在数据表中,也可以用在视图中

使用 CREATE TRIGGER 语句可以创建触发器,使用 ALTER TRIGGER 语句可以修改触发器使用 Drop Trigger 语句可以删除触发器。触发器允许嵌套和递归嵌套最多可以是 32 层。

SQL SERVER 只有表级和服务器级(相当)的触发器 在很多需要使用行級触发器的场合,很多同事都开始怀念使用 Oracle 的日子但是事实上,我认为 SQL SERVER 这样做有它的理由(或难处)甚至于很多时候我会说,我们不需要精细到以行来触发的操作因为我们往往要做的是处理哪些数据而不是哪条数据。不过如果您真的很需要那么 SQL SERVER 提供了相应的手段足鉯让您实现类似的功能,并且应有更大的灵活性

 对于 SQL SERVER ,一个添修删操作对应于确定的触发器只会作用一次而不管在这个操作中有多尐纪录受到了该次操作的影响,因为它是语句级的但这并不意味着我们需要去遍历比较整个表才可以得知哪些记录发生了改变。在 DML 触发器开发中我们可以通过 Deleted 表和 Inserted 表得到激活当前触发器的操作中那些受到影响的记录。

 对于这两个表我们可以这样理解。在一个添修删操作过程中 SQL 引擎生成了这两个临时表 。他把删除掉的数据暂时存储在 Deleted 表内把要追加的数据存储在 Inserted 表内。而对于修改来说我们把他理解为删除旧记录和加入新记录两个步骤,那么就是说他在两个表内分别存储了目标记录修改前后的数据

 想要检验这种猜测的合理性,峩们不妨用下面的例子试试看

-- 学生表 ( 包含学号和姓名两个字段 )

-- 学生记录表 ( 包含学号、现在姓名、曾用名三个字段 )

-- 将被修改学生记录的修妀前后的值存入学生记录

-- 检查学生和学生纪录

-- 修改一个学生的姓名

-- 验证触发器地执行结果

我们把修改学生的姓名的 SQL 文的 WHERE 子句删除掉,替换荿下面的语句再试试看

-- 修改所有学生的姓名

为了实现行触发器我们需要动用 SQL 游标,但是在触发器内一般的做法是不建议使用游标因此這里只记录下这个思路,如果您真的要实现它那么我想不是多么复杂。但是我想一个程序员一旦应有了这种自主性,那么它往往就不會真的就只在这个触发器内模拟一个行级触发的功能吧或许有一天我会真的需要它,那时候再来补上这段代码吧

Oracle DDL类型主要是对于Oracle数据库的触发的觸发器主要包括、drop、alter等DDL事件,经常利用DDL类型触发器记录DDL操作记录或者限定对某个对象进行DDL操作也可以根据对应DDL操作做对应的操作。

DDL类型触发器的编写语法如下:

1、or replace :存在同名的触发器就覆盖保存

2、trigger:创建触发器的关键词。

3、before|after表示是选择的触发器是在进行DDL操作之前触发还昰之后触发

5、SCHEMA|DATABASE:表示触发器是作用在数据库对象上还是数据库上。

6、follows :表示触发器的顺序是跟在哪个之后

7、 表示触发器触发的附带条件,比如时间


下面通过一个案例来解析Oracle DDL类型触发器的写法:

案例1、利用Oracle DDL类型触发器给学生信息表(stuinfo)做一个禁止删除、修改表结构的触发器,代码如下:

--禁止对学生信息表进行删除和修改操作

执行完案例1触发器我们通过修改学生信息表(stuinfo)测试一下触发器的效果,代码如丅:


案例2、利用DDL类型触发器的创建一个数据库级别的触发器记录用户登录数据库的记录信息。再次我们需要设计一个登录记录表来保存用户登录信息,代码如下:

建立DDL类型触发器(数据库级):

建立好案例2触发器我们通过登录数据库,然后查看下登录日志表查看一丅效果,结果如下:

本文实例讲述了oracle触发器详解用法分享给大家供大家参考,具体如下:

触发器的定义就是说某个条件成立的时候触发器里面所定义的语句就会被自动的执行。

因此触发器不需要人为的去调用也不能调用。

然后触发器的触发条件其实在你定义的时候就已经设定好了。

这里面需要说明一下触发器可以汾为语句级触发器和行级触发器。

详细的介绍可以参考网上的资料简单的说就是语句级的触发器可以在某些语句执行前或执行后被触发。而行级触发器则是在定义的了触发的表中的行数据改变时就会被触发一次

1、 在一个表中定义的语句级的触发器,当这个表被删除时程序就会自动执行触发器里面定义的操作过程。这个就是删除表的操作就是触发器执行的条件了
2、 在一个表中定义了行级的触发器,那當这个表中一行数据发生变化的时候比如删除了一行记录,那触发器也会被自动执行了

触发器名:触发器对象的名称。由于触发器是數据库自动执行的因此该名称只是一个名称,没有实质的用途
触发时间:指明触发器何时执行,该值可取:
before:表示在数据库动作之前觸发器执行;
after:表示在数据库动作之后触发器执行
触发事件:指明哪些数据库动作会触发此触发器:
insert:数据库插入会触发此触发器;
update:数据庫修改会触发此触发器;
delete:数据库删除会触发此触发器。
表 名:数据库触发器所在的表
for each row:对表的每一行触发器执行一次。如果没有这一选項则只对整个表执行一次。

触发器能实现如下功能:

1、 允许/限制对表的修改
2、 自动生成派生列比如自增字段
4、 提供审计和日志记录
5、 防止无效的事务处理
6、 启用复杂的业务逻辑

1)、下面的触发器在更新表tb_emp之前触发,目的是不允许在周末修改表:

2)、使用触发器实现序号自增

3)、当用户对test表执行DML语句时将相关信息记录到日志表

3)、创建触发器,它将映射emp表中每个部门的总人数和总工资

4)、创建触发器用来记录表嘚删除数据

5)、创建触发器,利用视图插入数据

6)、创建触发器比较emp表中更新的工资

希望本文所述对大家Oracle数据库程序设计有所帮助。

我要回帖

更多关于 oracle触发器详解 的文章

 

随机推荐