版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、SQL触发器语法语法CREATE TRIGGER trigger_name(触发器的名称)ON table | view (在其上执行触发器的表或视图) WITH ENCRYPTION (加密) FOR | AFTER | INSTEAD OF INSERT DELETE UPDATE WITH APPEND NOT FOR REPLICATION AS IF UPDATE ( column ) AND | OR UPDATE ( column ) .n | IF ( COLUMNS_UPDATED ( ) updated_bitmask )column_bitmask .n sql_stat
2、ement .n 参数trigger_name是触发器的名称。触发器名称必须符合可以选择是否指定触发器所有者名称。标识符 规则,并且在数据库中必须唯一。Table | view是在其上执行触发器的表或视图,有时称为触发器表或触发器视图。可以选择是否指定表或视图的所有者名称。WITH ENCRYPTION加密syscomments表中包含CREATE TRIGGER语句文本的条目。使用WITHENCRYPTION 可防止将触发器作为SQL Server复制的一部分发布。AFTER指定触发器只有在触发SQL语句中指定的所有操作都已成功执行后才激发。的引用级联操作和约束检查也必须成功完成后,才能执行
3、此触发器。如果仅指定FOR 关键字,则AFTER 是默认设置。不能在视图上定义AFTER 触发器。所有INSTEAD OF指定执行触发器而不是执行触发SQL语句,从而替代触发语句的操作。在表或视图上,每个INSERT 、 UPDATE 或 DELETE 语句最多可以定义一个INSTEAD OF 触发器。然而,可以在每个具有INSTEAD OF触发器的视图上定义视图。INSTEAD OF 触发器不能在WITH CHECK OPTION的可更新视图上定义。如果向指定了 WITH CHECKOPTION 选项的可更新视图添加INSTEAD OF 触发器, SQL Server将产生一个错误。用户必须
4、用ALTER VIEW 删除该选项后才能定义INSTEAD OF 触发器。 DELETE , INSERT , UPDATE 是指定在表或视图上执行哪些数据修改语句时将激活触发器的关键字。必须至少指定一个选项。在触发器定义中允许使用以任意顺序组合的这些关键字。如果指定的选项多于一个,需用逗号分隔这些选项。对于 INSTEAD OF触发器,不允许在具有ON DELETE级联操作引用关系的表上使用 DELETE 选项。同样,也不允许在具有用 UPDATE 选项。ON UPDATE级联操作引用关系的表上使WITH APPEND指定应该添加现有类型的其它触发器。只有当兼容级别是65或更低时,才需要使用
5、该可选子句。如果兼容级别是70或更高,则不必使用WITH APPEND 子句添加现有类型的其它触发器(这是兼容级别设置为70或更高的CREATE TRIGGER 的默认行为)。有关更多信息,请参见sp_dbcmptlevel。WITH APPEND 不能与INSTEAD OF触发器一起使用,或者,如果显式声明AFTER触发器,也不能使用该子句。只有当出于向后兼容而指定FOR 时(没有INSTEAD OF或 AFTER ),才能使用WITH APPEND。以后的版本将不支持WITH APPEND 和 FOR(将被解释为AFTER )。NOT FOR REPLICATION表示当复制进程更改触发器
6、所涉及的表时,不应执行该触发器。AS是触发器要执行的操作。sql_statement是触发器的条件和操作。触发器条件指定其它准则,以确定DELETE、 INSERT 或UPDATE 语句是否导致执行触发器操作。当尝试DELETE、INSERT 或 UPDATE 操作时, Transact-SQL语句中指定的触发器操作将生效。触发器可以包含任意数量和种类的Transact-SQL语句。触发器旨在根据数据修改语句检查或更改数据;它不应将数据返回给用户。触发器中的Transact-SQL语句常常包含控制流语言。CREATE TRIGGER 语句中使用几个特殊的表:* deleted和 inserte
7、d是逻辑(概念)表。这些表在结构上类似于定义触发器的表(也就是在其中尝试用户操作的表);这些表用于保存用户操作可能更改的行的旧值或新值。例如,若要检索deleted表中的所有值,请使用:SELECT *FROM deleted*如果兼容级别等于70 ,那么在DELETE、 INSERT 或 UPDATE 触发器中,SQLServer将不允许引用inserted和 deleted表中的text、 ntext或 image列。不能访问inserted和 deleted表中的text、ntext和 image值。若要在INSERT或UPDATE 触发器中检索新值,请将inserted表与原始更新表联
8、接。当兼容级别是65或更低时,对inserted或 deleted表中允许空值的text、ntext或 image列,将返回空值;如果这些列不可为空,则返回零长度字符串。当兼容级别是80或更高时,SQL Server允许在表或视图上通过INSTEAD OF 触发器更新text、 ntext或 image列。n是表示触发器中可以包含多条(column)语句,可以通过重复Transact-SQL UPDATE (column)语句的占位符。对于子句包含多列。IF UPDATEIF UPDATE (column)测试在指定的列上进行的INSERT或 UPDATE 操作,不能用于DELETE 操作。可
9、以指定多列。因为在ON 子句中指定了表名,所以在IF UPDATE子句中的列名前不要包含表名。若要测试在多个列上进行的INSERT或 UPDATE 操作,请在第一个操作后指定单独的UPDATE(column)子句。在INSERT操作中IF UPDATE将返回TRUE值,因为这些列插入了显式值或隐性(NULL)值。说明 IF UPDATE (column)子句的功能等同于IF 、 IF.ELSE或 WHILE语句,并且可以使用BEGIN.END语句块。有关更多信息,请参见控制流语言。可以在触发器主体中的任意位置使用UPDATE (column)。column是要测试 INSERT 或 UPDAT
10、E 操作的列名。该列可以是 SQL Server 数据类型。但是,计算列不能用于该环境中。有关更多信息,请参见数据类型。支持的任何IF (COLUMNS_UPDATED()测试是否插入或更新了提及的列,仅用于INSERT或 UPDATE 触发器中。COLUMNS_UPDATED返回 varbinary位模式,表示插入或更新了表中的哪些列。COLUMNS_UPDATED函数以从左到右的顺序返回位,最左边的为最不重要的位。最左边的位表示表中的第一列;向右的下一位表示第二列,依此类推。如果在表上创建的触发器包含8列以上,则COLUMNS_UPDATED返回多个字节,最左边的为最不重要的字节。在INS
11、ERT操作中COLUMNS_UPDATED将对所有列返回TRUE 值,因为这些列插入了显式值或隐性(NULL)值。可以在触发器主体中的任意位置使用COLUMNS_UPDATED。bitwise_operator是用于比较运算的位运算符。updated_bitmask是整型位掩码,表示实际更新或插入的列。例如,表C4 和 C5 。假定表t1上有 UPDATE 触发器,若要检查列新,指定值14 ;若要检查是否只有列C2有更新,指定值t1包含列C2 、C3 和2 。C1 、 C2、 C3、C4是否都有更comparison_operator是比较运算符。使用等号际进行了更新。使用大于号(=)(>
12、;)检查 updated_bitmask检查 updated_bitmask中指定的所有列是否都实中指定的任一列或某些列是否已更新。column_bitmask是要检查的列的整型位掩码,用来检查是否已更新或插入了这些列。注释触发器常常用于强制业务规则和数据完整性。SQL Server通过表创建语句( ALTERTABLE 和 CREATE TABLE)提供 声明引用完整性(DRI);但是DRI不提供数据库间的引用完整性。若要强制引用完整性(有关表的主键和外键之间关系的规则),请使用主键和外键约束(ALTER TABLE 和 CREATE TABLE 的 PRIMARY KEY 和 FOREIG
13、N KEY 关键字)。如果触发器表存在约束,则在INSTEAD OF触发器执行之后和AFTER触发器执行之前检查这些约束。如果违反了约束,则回滚INSTEAD OF触发器操作且不执行(激发)AFTER 触发器。可用 sp_settriggerorder指定表上第一个和最后一个执行的AFTER 触发器。在表上只能为每个INSERT 、 UPDATE 和 DELETE 操作指定一个第一个执行和一个最后一个执行的AFTER触发器。如果同一表上还有其它AFTER 触发器,则这些触发器将以随机顺序执行。如果 ALTER TRIGGER 语句更改了第一个或最后一个触发器,则将除去已修改触发器上设置的第一个
14、或最后一个特性,而且必须用sp_settriggerorder重置排序值。只有当触发SQL语句(包括所有与更新或删除的对象关联的引用级联操作和约束检查)成功执行后,AFTER 触发器才会执行。AFTER 触发器检查触发语句的运行效果,以及所有由触发语句引起的UPDATE 和 DELETE引用级联操作的效果。触发器限制CREATE TRIGGER 必须是批处理中的第一条语句,并且只能应用到一个表中。触发器只能在当前的数据库中创建,不过触发器可以引用当前数据库的外部对象。如果指定触发器所有者名称以限定触发器,请以相同的方式限定表名。在同一条 CREATE TRIGGER 语句中, 可以为多种用户操
15、作 (如 INSERT 和 UPDATE)定义相同的触发器操作。如果一个表的外键在DELETE/UPDATE操作上定义了级联,则不能在该表上定义INSTEAD OF DELETE/UPDATE触发器。在触发器内可以指定任意的SET语句。所选择的SET选项在触发器执行期间有效,并在触发器执行完后恢复到以前的设置。与使用存储过程一样,当触发器激发时,将向调用应用程序返回结果。若要避免由于触发器激发而向应用程序返回结果,请不要包含返回结果的SELECT 语句,也不要包含在触发器中进行变量赋值的语句。包含向用户返回结果的SELECT 语句或进行变量赋值的语句的触发器需要特殊处理;这些返回的结果必须写入
16、允许修改触发器表的每个应用程序中。如果必须在触发器中进行变量赋值,则应该在触发器的开头使用SET NOCOUNT语句以避免返回任何结果集。DELETE 触发器不能捕获TRUNCATE TABLE 语句。尽管TRUNCATE TABLE 语句实际上是没有WHERE 子句的DELETE(它删除所有行),但它是无日志记录的,因而不能执行触发器。因为TRUNCATE TABLE 语句的权限默认授予表所有者且不可转让,所以只有表所有者才需要考虑无意中用TRUNCATE TABLE 语句规避DELETE触发器的问题。无论有日志记录还是无日志记录,WRITETEXT 语句都不激活触发器。触发器中不允许以下T
17、ransact-SQL语句:ALTER DATABASE CREATE DATABASE DISK INITDISK RESIZE DROP DATABASE LOAD DATABASELOAD LOG RECONFIGURE RESTORE DATABASERESTORE LOG说明由于 SQL Server不支持系统表中的用户定义触发器,因此建议不要在系统表中创建用户定义触发器。多个触发器SQL Server允许为每个数据修改事件(DELETE、 INSERT 或 UPDATE)创建多个触发器。例如,如果对已有UPDATE 触发器的表执行CREATE TRIGGER FOR UPDATE,
18、则将创建另一个更新触发器。在早期版本中,在每个表上, 每个数据修改事件( INSERT、UPDATE 或 DELETE)只允许有一个触发器。说明如果触发器名称不同,则CREATE TRIGGER(兼容级别为70 )的默认行为是在现有的触发器中添加其它触发器。如果触发器名称相同,则SQL Server返回一条错误信息。但是,如果兼容级别等于或小于65 ,则使用CREATE TRIGGER 语句创建的新触发器将替换同一类型的任何现有触发器,即使触发器名称不同。有关更多信息,请参见 sp_dbcmptlevel 。递归触发器当在 sp_dboption 中启用 recursive triggers
19、设置时, SQL Server 还允许触发器的递归调用。递归触发器允许发生两种类型的递归:*间接递归*直接递归使用间接递归时,应用程序更新表T1 ,从而激发触发器TR1 ,该触发器更新表T2。在这种情况下,触发器T2将激发并更新T1 。使用直接递归时,应用程序更新表T1 ,从而激发触发器TR1 ,该触发器更新表T1。由于表T1被更新,触发器TR1再次激发,依此类推。下例既使用了间接触发器递归,又使用了直接触发器递归。假定在表T1中定义了两个更新触发器TR1和 TR2 。触发器TR1递归地更新表T1 。 UPDATE 语句使TR1和 TR2各执行一次。而TR1的执行将触发TR1 (递归)和TR2
20、的执行。给定触发器的 inserted和 deleted表只包含与唤醒调用触发器的UPDATE 语句相对应的行。说明只有启用sp_dboption的 recursivetriggers设置,才会发生上述行为。对于为给定事件定义的多个触发器,并没有确定的执行顺序。每个触发器都应是自包含的。禁用 recursive triggers设置只能禁止直接递归。若要也禁用间接递归,请使用 sp_configure将 nested triggers服务器选项设置为0 。如果任一触发器执行了ROLLBACK TRANSACTION 语句,则无论嵌套级是多少,都不会进一步执行其它触发器。嵌套触发器触发器最多可以
21、嵌套 32 层。如果一个触发器更改了包含另一个触发器的表,则第二个触发器将激活,然后该触发器可以再调用第三个触发器,依此类推。如果链中任意一个触发器引发了无限循环,则会超出嵌套级限制,从而导致取消触发器。若要禁用嵌套触发器,请用 sp_configure 将 nested triggers 选项设置为 0 (关闭)。默认配置允许嵌套触发器。如果嵌套触发器是关闭的,则也将禁用递归触发器,与sp_dboption的 recursive triggers设置无关。延迟名称解析SQL Server允许 Transact-SQL存储过程、触发器和批处理引用编译时不存在的表。这种能力称为延迟名称解析。但是
22、,如果Transact-SQL存储过程、触发器或批处理引用在存储过程或触发器中定义的表,则只有当兼容级别设置(通过执行sp_dbcmptlevel设置)等于65时,才会在创建时发出警告。如果使用批处理,则在编译时发出警告。如果引用的表不存在,将在运行时返回错误信息。有关更多信息,请参见延迟名称解析和编译。权限CREATE TRIGGER 权限默认授予定义触发器的表所有者、sysadmin固定服务器角色成员以及db_owner和 db_ddladmin固定数据库角色成员,并且不可转让。若要检索表或视图中的数据,用户必须在表或视图中拥有SELECT 语句权限。若要更新表或视图的内容,用户必须在表或
23、视图中拥有INSERT 、 DELETE 和 UPDATE句权限。语如果视图中存在 INSTEAD OF 触发器, 用户必须在该视图中有 INSERT 、DELETE 和 UPDATE 特权,以对该视图发出 INSERT 、 DELETE 和 UPDATE 语句,而不管实际上是否在视图上执行了这样的操作。示例A. 使用带有提醒消息的触发器当有人试图在titles表中添加或更改数据时,下例将向客户端 显示一条消息。说明消息 50009是 sysmessages中的用户定义消息。有关创建用户定义消息的更多信息,请参见sp_addmessage。USE pubs当 titles表更改时,下例将电子邮
24、件发送给指定的人员(MaryM)。USE pubs'Don''t forget to print a report for the distributors.'GOC.在 employee和 jobs表之间使用触发器业务规则由于 CHECK 约束只能引用定义了列级或表级约束的列,表间的任何约束(在下例中是指业务规则)都必须定义为触发器。下例创建一个触发器,当插入或更新雇员工作级别(job_lvls)时,该触发器检查指定雇员的工作级别(由此决定薪水)是否处于为该工作定义的范围内。若要获得适当的范围,必须引用jobs表。USE pubsIF EXISTS (SELE
25、CT name FROM sysobjectsWHERE name = 'employee_insupd' AND type = 'TR')DROP TRIGGER employee_insupdGOCREATE TRIGGER employee_insupdON employeeFOR INSERT, UPDATEAS/* Get the range of level for this job type from the jobs table. */ DECLARE min_lvl tinyint,max_lvl tinyint,emp_lvl tinyint
26、,job_id smallintSELECT min_lvl = min_lvl,max_lvl = max_lvl,emp_lvl = i.job_lvl,job_id = i.job_idFROM employee e INNER JOIN inserted i ON e.emp_id = i.emp_id JOIN jobs j ON j.job_id = i.job_idIF (job_id = 1) and (emp_lvl <> 10)BEGINRAISERROR ('Job id 1 expects the default level of 10.',
27、 16, 1)ROLLBACK TRANSACTIONENDELSEIF NOT (emp_lvl BETWEEN min_lvl AND max_lvl)BEGINRAISERROR ('The level for job_id:%d should be between %d and %d.', 16, 1, job_id, min_lvl, max_lvl)ROLLBACK TRANSACTIONENDD. 使用延迟名称解析下例创建两个触发器以说明延迟名称解析。USE pubsIF EXISTS (SELECT name FROM sysobjectsWHERE name
28、= 'trig1' AND type = 'TR')DROP TRIGGER trig1GO- Creating a trigger on a nonexistent table. CREATE TRIGGER trig1on authorsFOR INSERT, UPDATE, DELETE ASSELECT a.au_lname, a.au_fname, FROM authors a INNER JOIN does_not_exist x- Here is the statement to actually see the text of th
29、e trigger. SELECT o.id, c.textFROM sysobjects o INNER JOIN syscomments cON o.id = c.idWHERE o.type = 'TR' and = 'trig1'- Creating a trigger on an existing table, but with a nonexistent- column.- Here is the statement to actually see the text of the trigger. SELECT o.id, c.text
30、FROM sysobjects o INNER JOIN syscomments c ON o.id = c.idWHERE o.type = 'TR' and = 'trig2'E.使用 COLUMNS_UPDATED下例创建两个表:一个employeeData表和一个auditEmployeeData表。人力资源部的成员可以修改employeeData表,该表包含敏感的雇员薪水信息。如果更改了雇员的社会保险号码(SSN) 、年薪或银行帐户,则生成审核记录并插入到auditEmployeeData审核表。通过使用COLUMNS_UPDATED()
31、 功能,可以快速测试对这些包含敏感雇员信息的列所做的更改。只有在试图检测对表中的前8列所做的更改时,COLUMNS_UPDATED()才起作用。USE pubsIF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'employeeData')DROP TABLE employeeDataIF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'auditEmployee
32、Data') DROP TABLE auditEmployeeDataGOCREATE TABLE employeeData (emp_id int NOT NULL,emp_bankAccountNumber char (10) NOT NULL,emp_salary int NOT NULL,emp_SSN char (11) NOT NULL,emp_lname nchar (32) NOT NULL,emp_fname nchar (32) NOT NULL,emp_manager int NOT NULL)GOCREATE TABLE auditEmployeeData (a
33、udit_log_id uniqueidentifier DEFAULT NEWID(),audit_log_type char (3) NOT NULL,audit_emp_id int NOT NULL,audit_emp_bankAccountNumber char (10) NULL,audit_emp_salary int NULL,audit_emp_SSN char (11) NULL,audit_user sysname DEFAULT SUSER_SNAME(),audit_changed datetime DEFAULT GETDATE()GOCREATE TRIGGER
34、updEmployeeDataON employeeDataFOR update AS/*Checkwhethercolumns2, 3 or 4 has been updated.Ifany or all2, 3 or 4 have been changed, create an audit record. The bitmask is:power(2,(2-1)+power(2,(3-1)+power(2,(4-1)= 14. To checkifall3, and 4 are updated, use = 14 in place of >0 (below).*/of columns
35、columns2,IF (COLUMNS_UPDATED() & 14) > 0/*Use IF (COLUMNS_UPDATED() & 14) = 14 to see if all of columns 2, 3, and 4 are updated.*/BEGIN- Audit OLD record.INSERT INTO auditEmployeeData(audit_log_type,audit_emp_id,audit_emp_bankAccountNumber,audit_emp_salary,audit_emp_SSN)SELECT 'OLD
36、9;,del.emp_id,del.emp_bankAccountNumber,del.emp_salary,del.emp_SSNFROM deleted del- Audit NEW record.INSERT INTO auditEmployeeData(audit_log_type,audit_emp_id,audit_emp_bankAccountNumber,audit_emp_salary,audit_emp_SSN)SELECT 'NEW',ins.emp_id,ins.emp_bankAccountNumber,ins.emp_salary,ins.emp_SSNFROM inserted insENDGO/*Inserting a new employee does no
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 感恩老师演讲稿(集锦15篇)
- 小班保育员小结
- 婚礼上的致辞汇编15篇
- 易错题25 古代诗歌阅读之情感主旨题-不会见微知著探究主旨高考语文备战2025年高考易错题(新高考专用)含解析
- 2018安徽道法试卷+答案+解析
- 急救培训心得体会汇编15篇
- 初级会计实务-《初级会计实务》模考试卷853
- 中国电池预制舱行业投资分析、市场运行态势研究报告-智研咨询发布(2024版)
- 智研咨询-中国急救中心行业市场调查、产业链全景、需求规模预测报告(2024版)
- 智研咨询发布:2024年中国心脏脉冲电场消融系统(PFA)行业市场现状及投资前景分析报告
- 护理人文知识培训课件
- 2025年春新人教版数学七年级下册教学课件 7.2.3 平行线的性质(第1课时)
- 安徽省合肥市2025年高三第一次教学质量检测地理试题(含答案)
- 统编版八年级下册语文第三单元名著导读《经典常谈》阅读指导 学案(含练习题及答案)
- 风光储储能项目PCS舱、电池舱吊装方案
- TTJSFB 002-2024 绿色融资租赁项目评价指南
- 光伏项目安全培训课件
- 全面解读新能源法律风险与应对措施
- 民法学详细教案
- 浙江省杭州市2023年中考一模语文试题及答案
- 上海市杨浦区2022届初三中考二模英语试卷+答案
评论
0/150
提交评论