天天看点

Sql 触发器

        触发器是一种特殊的存储过程﹐它不能被显式地调用﹐而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。所以触发器可以用来实现对表实施复杂的完整性约束。 

        触发器在数据库里以独立的对象存储,与存储过程不同的是,存储过程通过其他程序来启动运行,而触发器是由一个事件来启动运行。即当某个事件发生时,触发器自动地隐式运行。并且,触发器不能接收参数。

        触发器对象定义了触发器的特征和被调用时采取的行动。而这些动作是通过一个或多个sql语句来实现的。sql支持3种类型的触发器:insert(插入)、update(更新)和delete(删除)。当向表中插入数据、更新数据或删除数据时,触发器就被调用。通过给表定义一个或多个触发器,可以指定哪个数据修改时,可以激发触发器。

一、sql server

        sql server为每个触发器都创建了两个专用表:inserted表和deleted表。这两个表由系统来维护﹐它们存在于内存中而不是在数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。 触发器执行完成后﹐与该触发器相关的这两个表也被删除。 

        deleted表存放由于执行delete或update语句而要从表中删除的所有行。 

        inserted表存放由于执行insert或update语句而要向表中插入的所有行。

Sql 触发器

        在sqlserver中,可以采用createtrigger命令创建触发器。语法如下:

trigger_name:为用户要创建的触发器的名字,触发器的名字必须符合sqlserver的命名规则,且其名字在当前数据库中必须是惟一的。

table、view:与触发器相关联的表或视图的名字,并且该表或视图必须已经在数据库中存在。

withencryption:表示对含有createtrigger文本的syscomments表进行加密,防止用户通过查询syscomments表获取触发器的代码。

after:表示只有执行了指定的操作(insert、delete、或update)之后,触发器才被激活,执行触发器中的sql语句。

for:表示为after触发器,且该触发器仅能在表上创建。

insteadof:指定触发器为insteadof触发器

小注:每个表最多只能有一个insteadof(insert、update、delete)触发器。然而可以为每个表创建多个视图,对每个视图都可以有不同的insteadof触发器。

delete、insert、update:指明执行哪种操作,将激活触发器。至少要包含3种操作类型种的一种,也可以是3种操作语句的任意组合。其中三者的顺序不受限制,且各选项要用逗号隔开。

notforreplication:告诉dbms,当复制表时,触发器不能被执行。as:后面列出触发器将要执行的动作。

ifupdatecolumn:用来测定对某一确定列是insert操作还是update操作。如果要测试insert还是update操作的列多于一列,可用and或or逻辑连接向ifupdate子句添加所希望的附加列名。

ifcolumns_updated():仅在insert和update类型的触发器中使用,检查列是被更新还是被插入。

bitwise_operator:代表位逻辑运算符,常用“&”。

updated_bitmask:表示列的整位掩码。其中最右边的位表示表或视图的第1列,左边第2位代表第2列,依此类推。

comparison_operator:表示比较操作符。可以是“=”或者“>”。“=”表示检查在updated_bitmask中定义的所有列是否都被更新,用“>”表示检查是否在updated_bitmask小注:

为了便于理解,这里给出一个使用ifcolumns_updated()子句的例子。如果表t包括c1、c2、c3、c4、c5和c66列,为了检查c2、c4或者c6列是否更新过,可使用42(二进制表示为“101010”)作为掩码,表示为:if(columns_updated()&42)>0;如果检查c2、c4和c63列是否都被更新过,表示为:if(columns_updated()&42)=42

sql_statement:代表包含在触发器中的处理语句。

当不再需要触发器时,可用droptrigger语句删除触发器。语法如下:

二、oracle

        在oracle中共有3种类型的触发器:dml触发器、替代触发器和系统触发器。

        dml触发器:oracle可以在dml语句(insert、update、delete)进行触发,可以在dml操作前或操作后进行触发,并且可以对每个行或语句上进行触发。替代触发器(insteadof):与sqlserver中的insteadof触发器类似,由于在oracle里,不能直接对由两个以上的表建立的视图进行操作。所以给出了替代触发器。系统触发器:从oracle8i开始,提供了第三种类型的触发器叫系统触发器。它可以在oracle的事件中进行触发,如oracle系统的启动与关闭等。

        在oracle中,触发器的创建也是通过createtrigger语句来实现的,但与sqlserver中的触发器创建语法有较大的差别。语法如下:

        说明如下:

rigger_name:为触发器的名字。在oracle中,触发器名与存储过程名字不一样,它是单独的名字空间,因而触发器名可以和表或存储过程有相同的名字。

before|after:指明了触发器是在数据修改前(before),还是修改后(after)被调用。

trigger_event:为触发器事件,可以是insert、update或delete。如果要创建替代触发器,则只需在触发事件前加上关键词insteadof即可。

on:子句则包含了目标表的名称,也就是触发器应用的表。

foreachrow:指明每次插入、更新或删除一行时就调用触发器。

when:是可选的,可以定义搜索条件,来限制调用触发器时的搜索范围。

trigger_body:为触发器执行的sql语句,这些语句必须被放在begin……end块中。

另外,在oracle中,触发器的应用受到一定的限制,主要的限制条件有以下几个。触发器中可以包括dml语句,但不能使用控制语句、commit语句、rollback语句、svaepoint语句。然而,对于“系统触发器”,则可以使用create语句、alter语句或者drop语句。由触发器所调用的存储过程或函数也不能使用控制语句。触发器中不能使用long、longraw数据类型。