Sql 触发器

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

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

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

一、SQL Server

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

        Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。 
        Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。

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

CREATETRIGGERtrigger_nameON{table|view}[WITHENCRYPTION]{
{{FOR|AFTER|INSTEADOF}{[DELETE][,][INSERT][,][UPDATE]}
[NOTFORREPLICATION]
AS
[{IFUPDATE(column)
[{AND|OR}UPDATE(column)]
[...n]
|IF(COLUMNS_UPDATED(){bitwise_operator}updated_bitmask)
{comparison_operator}column_bitmask[...n]
}]
sql_statement[...n]}}
  • 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语句删除触发器。语法如下:

    DROP  TRIGGER  trigger_name[...n]

二、Oracle

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

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

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

CREATE  TRIGGER  trigger_name
[BEFORE|AFTER]
trigger_event
ON  table_reference
[FOREACHROW[WHENtrigger_condition]]trigger_body

        说明如下:

  • 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数据类型。

本文来自百度文库:点击打开链接

时间: 2024-11-03 12:15:45

Sql 触发器的相关文章

如何使用SQL触发器进行备份数据库?

sql|触发器|备份|数据库 首先,你需要建立测试数据表,一个用于插入数据:test3,另外一个作为备份:test3_bak 以下是引用片段为例: create table test3(id int primary key not null identity(1,1),uname varchar(20),uage int); create table test3_bak(id int primary key not null identity(1,1),bid int,uname varchar

SQL触发器实例讲解

SQL触发器实例1 定义: 何为触发器?在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序.触发器是一个特殊的存储过程.  常见的触发器有三种:分别应用于Insert , Update , Delete 事件.  我为什么要使用触发器?比如,这么两个表: 复制代码代码如下: Create Table Student( --学生表  StudentID int primary key, --学号  ....  )  Create Table BorrowRec

sql触发器结果没有更新

问题描述 sql触发器结果没有更新 create trigger tr_cost on stu_inf for updateas declare @bukao intbegin select @bukao=补考次数from v_cost if @bukao>=2 begin update stu_inf set 学习费用=学习费用 * 1.1 where 学员编号 in(select 学员编号 from stu_inf) end end # 请问这个触发器为什么在表中没有显示结果,stu_inf

sqlserver 存储过程- 新手请求帮助SQL触发器

问题描述 新手请求帮助SQL触发器 set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER TRIGGER [tr_yskq1] ON [dbo].[yskq1] FOR INSERT AS declare @bh varchar(10), @date1 datetime, @time1 varchar(30), @timeA varchar(30), @timeB varchar(30), @bmmc varchar(50), @jh bigin

sqlserver2008触发器-SQL触发器进行更新操作时 用insert添加发生主键冲突

问题描述 SQL触发器进行更新操作时 用insert添加发生主键冲突 环境:SQLserver 2008 创建的表 --库存表(还有多少商品)ID 名称 库存数量 --销售表(卖了多少商品)ID 销售数量 create table StockInfo ( ProID int primary key identity(1,1), ProName nvarchar(20) not null, ProNumber int not null ) go create table SellTab--销售表

sql 触发器问题!求帮忙啊

问题描述 sql 触发器问题!求帮忙啊 使用触发器控制表插入操作时某个字段不能为空,如果为空回滚操作. 这个怎么搞!! 解决方案 很简单啊,直接设置字段不为空就行了 解决方案二: 这个为什么用触发器,在建表的时候就设置该字段不能为空

SQL 触发器批量删除数据

问题描述 SQL 触发器批量删除数据 有A主表,B表为临时表两个表,两个表的结构完全相同,主键分别为ch_billno,ch_tableno,ssid,我想做一个触发器,当A表插入主键数据时,把临时表中存在相同主键的数据删除,插入数据的时候会用到sqlbulkcopy方式插入,只会引发一次insert操作. 解决方案 亲测可用, 楼主速速采纳吧, 呵呵 --1. 创建测试表 A,B 及测试数据 IF OBJECT_ID('dbo.A') IS NOT nuLL BEGIN DROP TABLE

SQL触发器在插入记录中根据A字段自动给B字段赋值

问题描述 SQL触发器在插入记录中根据A字段自动给B字段赋值 假如我有一个人员信息表,表的字段结构如下: 姓名 性别 性别值 性别字段,如果为男,性别值为0: 性别字段,如果为女,性别值为1: 性别字段,如果为中性,性别值为3: 在插入记录的时候,只会插入 姓名和性别两个字段.现在想要通过触发器来自动填充后面一个'性别值'字段. 这个如何实现呢?求指导.插入的时候,可能一次性插入多条记录. (MSSQL 2008数据库) 解决方案 sqlserver貌似是不支持oracle的for each r

sql-新手学习SQL触发器的问题

问题描述 新手学习SQL触发器的问题 A库A表与B库的A表结构完全一样! 触发器该怎么写实现 才能实现 增加 修改 删除A库A表,同时对B库A表 做同样的动作. 也就是同步2个数据库 解决方案 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 解决方案二: 不太懂...???..???????? 解决方案三: 不太懂...???..???????? 解决方案四: 不知道呢............... 解决方案五: 求采纳,缺积分.加油!我看好你 解决方案六: create trigger test after

在SQL触发器或存储过程中获取在程序登录的用户_MsSql

实现一个AuditLog的功能,是B/S结构专案. 每个用户可以登录系统,在程序中操作数据(添加,更新和删除)需要实现记录操作跟踪.是谁添加,更新和删除的,这些信息将会插入至AuditLog表中. 一般情况之下,在SQL的触发器中,只能取到(SQL验证sa:Windows验证Domain\xxx).这些用户名,达不到效果,不能真正反映到是谁操作的. 下面是让你清楚,怎样实现在SQL触发器或存储过程中获取在程序登录的用户,是在插入,更新或删除的存储过程,把登录程序当前用户传入进去.在存储过程中,再