数据库数据库完整性触发器.ppt
补充:1).T-SQL语言简介,T-SQL的存储过程:由SQL语句组成,分系统存储过程和用户自定义存储过程。,T-SQL组成:SQL语句、函数和存储过程。,T-SQL的子语言:数据定义语言DDL(Data Definition Language)、数据操纵语言DML(Data Manipulation Language)和数据控制语言DCL(Data Control Language)。,T-SQL的函数:系统函数、聚集函数、数学函数、字符串函数、数据类型转换函数和日期函数等。,2).T-SQL编程,表示及概念:变量名,由用户定义并使用。,A.注释(Comment)方式,(1)多行时,用/*.*/,(2)单行时,用-,B.变量,局部变量定义:DECLARE 变量名 类型,n DECLARE myqty int,msg varchar(40),(1)局部变量,说明:(1)变量一旦定义,系统自动赋NULL值。,(2)对局部变量的赋值用SELECT语句。SELECT myqty=60,表示及概念:变量名,由系统定义,用户可使用之。,作用:用于指明系统运行过程中的运行状态,用户只能引用,不能修改和定义。,(2)全局变量,常用的全局变量:,(1)error:返回最后一个语句产生的错误码。,(2)rowcount:返回语句执行后受影响的行数。,(3)version:SQL SERVER版本号。,(4)trancount:事务计数。,(5)transtate:事务状态(成功、失败)。,C.SELECT用法,(1)查看表或视图的内容;,(2)执行函数,返回值到客户端:SELECT db_name(),直接赋值:Select xxxx=2。一次只能一个。,从表中提取值赋给变量(应保证是唯一行且类型一致)。,(3)给变量赋值,(4)查看变量值:Select 变量,示例:SELECT tp=price FROM titles T WHERE T.id=Bu1032,D.流程控制语句,(1)IF(条件关系式)ELSE IF:如果关系式含有SELECT语句,则该SELECT语句须用圆括号括起,其嵌套级别最多为150;,IF(SELECT AVG(price)FROM titles)=20 UPDATE titles SET price=price*1.3ELSE PRINT 平均价格未知!,(2)BEGIN.END:用于界定由多条SQL语句组成的语句块;示例:DECLARE avg_price money SELECT avg_price=AVG(price)FROM titles IF avg_price 20 BEGIN UPDATE titles SET price=price*1.5 PRINT 价格提高50%END,(3)WHILE.BREAK/CONTINUE:循环控制语句 示例:WHILE(SELECT AVG(price)FROM titles)30 BREAK END,(4)GOTO.:跳到用户定义的标号处;,(5)RETURN:无条件退出;,(6)IF EXISTS/IF NOT EXISTS:是否有数据存在 IF NOT EXISTS(SELECT*FROM titles WHERE title_id=010101)BEGIN PRINT 没有010101的任何记录 RETURN END,E.信息显示,(1)Print.,(2)Print msg,(3)用参数嵌套形式加入不同的值:Print.%1!.%2!.,参数1,参数2,,(7)WAITFOR:延迟某段时间,示例:WAITFOR DELAY 00:30:00/*延迟30分钟*/,语法:WAITFOR DELAY 日期时间格式的时间值|TIME 时间|,F.RAISERROR,用途:系统有很多系统信息及其代码(代码值在两万以下),用户也可用RAISERROR,自己定义错误信息及其代码(其代码值应在两万以上)。,语法:RAISERROR 错误代码 错误信息|局部变量,参数表 例:DECLARE table_name varchar(30)SELECT table_name=TITLERAISERROR 99999 表%1!不存在。,table_name,3).T-SQL提供的函数,A.字符串操作,(1)连接操作:+,(2)convert函数,作用:将表达式按指定风格转换成指定的类型,其中的style只用于日期类型到字符串的转换。,语法:convert(类型符,表达式,style),convert(char(10),pubdate,105)其中,pubdate为日期型。,示例:,(3)日期=字符串,B.有关日期的几个函数,(1)getdate(),(2)datename()与datepart(),datename(日期元素,日期表达式):以字符串形式返回日期元素指定的日期的名字,用途:将服务器OS的时间送客户机。,示例:SELECT getdate(),datepart(日期元素,日期表达式):以数字形式返回日期元素指定的日期的名字,日期元素及其指定返回的日期部分为:,yy:返回日期表达式中的年year或年数。,qq:返回日期表达式表示的季quarter或季数。,mm:返回日期表达式中的月month或月数。,dw:返回日期表达式表示的星期几day of week。,dy:返回日期表达式表示的一年中的第几天day of year,dd:返回日期表达式中的天或天数day。,wk:返回日期表达式表示的一年中的第几个星期week或星期数。,hh:返回日期表达式中的小时hour或小时数。,(3)dateadd()与datediff(),dateadd(日期元素,数值,日期表达式):将数值转换成日期元素指定的部分加到日期表达式上返回。,datediff(日期元素,较早日期表达式,较晚日期表达式):两个日期相减后,按日期元素指定部分转化后返回。,示例:,Select datename(mm,pubdate)from titiles where title_id=Bu1032返回June,如用datepart则返回 6。,C.数学函数,4)存储过程,创建存储过程执行存储过程查看和修改存储过程重命名和删除存储过程,存储过程的概念,SQL Server提供了一种方法,它可以将一些固定的操作集中起来由SQL Server数据库服务器来完成,以实现某个任务,这种方法就是存储过程。在SQL Server中存储过程分为两类:即系统提供的存储过程和用户自定义的存储过程。,创建存储过程,在SQL Server中,可以使用三种方法创建存储过程:使用创建存储过程向导创建存储过程。利用SQL Server 企业管理器创建存储过程。使用Transact-SQL语句中的CREATE PROCEDURE命令创建存储过程。,创建存储过程时,需要确定存储过程的三个组成部分:,所有的输入参数以及传给调用者的输出参数。被执行的针对数据库的操作语句,包括调用其它存储过程的语句。返回给调用者的状态值,以指明调用是成功还是失败。,1.使用创建存储过程向导创建存储过程,在企业管理器中,选择工具菜单中的向导选项,选择“创建存储过程向导”,则出现欢迎使用创建存储过程向导对话框。根据图提示可完成创建存储过程。,新建SQL Server组,欢迎使用创建存储过程向导对话框,选择数据库对话框,选择数据库对象对话框,完成创建存储过程向导对话框,编辑存储过程属性对话框,编辑存储过程SQL对话框,2.使用SQL Server 企业管理器创建存储过程,()在SQL Server企业管理器中,选择指定的服务器和数据库,用右键单击要创建存储过程的数据库,在弹出的快捷菜单中选择“新建”选项,再选择下一级菜单中的“存储过程”选项,如图5-77所示;或者用右键单击存储过程图标,从弹出的快捷菜单中选择“新建存储过程”选项,如图5-78所示。均会出现创建存储过程对话框。()在文本框中可以输入创建存储过程的T_SQL语句,单击“检查语法”,则可以检查语法是否正确;单击“确定”按钮,即可保存该存储过程。如果要设置权限,单击“权限”按钮。,选择新建存储过程对话框(1),选择新建存储过程对话框(2),新建存储过程对话框,设置权限对话框,3.使用Transact-SQL语句中的CREATE PROCEDURE命令创建存储过程,创建存储过程前,应该考虑下列几个事项:不能将 CREATE PROCEDURE 语句与其它 SQL 语句组合到单个批处理中。创建存储过程的权限默认属于数据库所有者,该所有者可将此权限授予其他用户。存储过程是数据库对象,其名称必须遵守标识符规则。只能在当前数据库中创建存储过程。一个存储过程的最大尺寸为128M。,使用CREATE PROCEDURE创建存储过程的语法形式如下:,CREATEPROCEDUREprocedure_name;number parameterdata_type VARYING=defaultOUTPUT,.n WITHRECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION FORREPLICATION AS sql_statement.n,用CREATE PROCEDURE创建存储过程的语法参数的意义如下:,procedure_name:用于指定要创建的存储过程的名称。number:该参数是可选的整数,它用来对同名的存储过程分组,以便用一条 DROP PROCEDURE 语句即可将同组的过程一起除去。parameter:过程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。data_type:用于指定参数的数据类型。VARYING:用于指定作为输出OUTPUT参数支持的结果集。Default:用于指定参数的默认值。OUTPUT:表明该参数是一个返回参数。,RECOMPILE:表明 SQL Server 不会保存该存储过程的执行计划。ENCRYPTION:表示 SQL Server 加密了 syscomments 表,该表的text字段是包含 CREATE PROCEDURE 语句的存储过程文本。FOR REPLICATION:用于指定不能在订阅服务器上执行为复制创建的存储过程。AS:用于指定该存储过程要执行的操作。sql_statement:是存储过程中要包含的任意数目和类型的 Transact-SQL 语句。,例:创建存储过程,1.建立不带参数的存储过程 use studentcopy go create procedure p_sc1 As Select sno,grade From sc go 执行不带参数的execute 语句Use studentcopyGoExecute p_sc1,2.建立带参数的存储过程Use studentcopy goIf exists(select name from sysobjects where name=p_sc and type=p)Drop procedure p_scGoCreate procedure p_sc sno char(7),cno char(10)As Select sname,cno,gradeFrom student join sc on student.sno=sc.snoWhere sc.sno=sno and cno=cnogo带参数的execute语句execute p_sc 参数,3.带输出参数的存储过程 use studentcopy go create procedure mathadd m1 int,m2 int,result int output as set result=m1+m2 Go调用带参数的存储过程Use studentcopyGoDeclare answer intExecute mathadd 8,10,answer outputSelect answer,查看和修改存储过程,查看存储过程 存储过程被创建之后,它的名字就存储在系统表sysobjects中,它的源代码存放在系统表syscomments中。可以使用使用企业管理器或系统存储过程来查看用户创建的存储过程。,(1)使用企业管理器查看用户创建的存储过程,在企业管理器中,打开指定的服务器和数据库项,选择要创建存储过程的数据库,单击存储过程文件夹,此时在右边的页框中显示该数据库的所有存储过程。用右键单击要查看的存储过程,从弹出的快捷菜单中选择属性选项,此时便可以看到存储过程的源代码。,(2)使用系统存储过程来查看用户创建的存储过程,可供使用的系统存储过程及其语法形式如下:sp_help:用于显示存储过程的参数及其数据类型sp_help objname=name参数name为要查看的存储过程的名称。sp_helptext:用于显示存储过程的源代码 sp_helptext objname=name参数name为要查看的存储过程的名称。sp_depends:用于显示和存储过程相关的数据库对象sp_depends objname=object参数object为要查看依赖关系的存储过程的名称。sp_stored_procedures:用于返回当前数据库中的存储过程列表,2.修改存储过程,存储过程可以根据用户的要求或者基表定义的改变而改变。使用ALTER PROCEDURE语句可以更改先前通过执行 CREATE PROCEDURE 语句创建的过程,但不会更改权限,也不影响相关的存储过程或触发器。其语法形式如下:ALTERPROCEDUREprocedure_name;number parameterdata_type VARYING=defaultOUTPUT,.n WITHRECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTIONFORREPLICATION ASsql_statement.n,重命名和删除存储过程,1.重命名存储过程修改存储过程的名称可以使用系统存储过程sp_rename,其语法形式如下:sp_rename 原存储过程名称,新存储过程名称另外,通过企业管理器也可以修改存储过程的名称。,2.删除存储过程,删除存储过程可以使用DROP命令,DROP命令可以将一个或者多个存储过程或者存储过程组从当前数据库中删除,其语法形式如下:drop procedure procedure,n当然,利用企业管理器也可以很方便地删除存储过程。,5)触发器概述 触发器是一种特殊类型的存储过程,触发器主要是通过事件进行触发而被执行,而存储过程可以通过存储过程名字而被直接调用。当对某一表进行如UPDATE,INSERT,DELETE这些操作时,SQL Server就会自动执行触发器所定义的SQL语句。从而确保对数据的处理必须符合这些SQL语句定义的规则。触发器的主要作用就是其能够实现由主键和外键所不能保证的参照完整性和数据的一致性。除此之外,触发器还有其他许多不同的功能:,(1)强化约束 触发器能够实现比CHECK语句更为复杂的约束。(2)跟踪变化 触发器可以侦测数据库内的操作,从而不允许数据库未 经许可的指定更新和变化。(3)级联运行 触发器可以侦测数据库内的操作,并自动地级联影响整 个数据库的各项内容。例如,某个表上的触发器中包含 有另外一个表的数据操作(如删除、更新、插入)而该 操作也导致该表上的触发器被触发。,(4)存储过程的调用 为了响应数据库更新,触发器可以调用一个或多个存储过程,甚至可以通过外部过程的调用而在DBMS(数据库管理系统)本身之外进行操作。由此可见,触发器可以解决高级形式的业务规则或复杂行为限制以及实现定制记录等一些方面的问题。总体而言,触发器性能通常比较低,当运行触发器时,系统处理的大部分时间花费在参照其他表的这一处理上,因为这些表既不在内存中也不在数据库设备上,而删除表和插入表总是位于内存中。可见触发器所参照的其他表的位置决定了操作要花费的时间长短。,SQL Server 2000支持两种类型的触发器:AFTER触发器和INSTEAD OF触发器。,6)触发器原理 SQL Server将数据写入数据库之前先校验规则和默认值,类似于一种信息“预过滤器”,避免某些数据项会影响数据库完整性造成数据库中的数据冗余。触发器是“后过滤器”,它在数据修改通过所有规则、默认值之后才执行。触发器是存储过程的特殊类型,它在对表进行插入、修改或删除操作时执行。如果触发器请求失败,将拒绝修改信息,并返回错误信息。,触发器常用来加强业务规则和数据完整性。SQL Server通过表的创建语句(ALTER TABLE 和CREATE TABLE)提供了声明引用完整性(DRI)。然而DRI不能提供跨数据库的引用完整性。引用完整性可以通过定义主键和外键来实现。如果约束是存在于触发器表中的,则它们可以在INSTEAD OF触发器执行之后与AFTER触发器执行之前被检查。如果与约束冲突,则INSTEAD OF触发器动作将回滚,并且AFTER触发器不会执行。,每个触发器有两个特殊的表插入表和删除表。这两个表是逻辑表,并且这两个表是由系统管理的,存储在内存中,不是存储在数据库中,因此不允许用户直接对其修改。这两个表的结构总是与被该触发器作用的表有相同的表结构。这两个表是动态驻留在内存中,当触发器工作完成这两个表也被删除。这两个表主要保存因用户操作而被影响到的原数据值或新数据值。另外,这两个表是只读的,即用户不能向这两个表写入内容但可以引用表中的数据。,(1)inserted表 根据触发器中的语句所执行的操作类型的不同,执行一系列触发器可以创建一个或者两个临时表(inserted表和deleted表),也可两个都创建。表1说明了在进行何种查询时,触发器创建哪些表。表1 触发器创建的表触发器类型 创建inserted 表 创建deleted 表INSERT 是 否UPDATE 是 是DELETE 否 是,应当了解的是:inserted 表和deleted 表只能被创建它们的触发器引用,inserted表和deleted表的范围仅限于该触发器,因此导致了这些表的瞬时性。如果一个触发器调用了一个存储过程,该存储过程不会对触发器触发时所创建的任何一个表产生影响。当一个记录插入表中时,相应的插入触发器创建一个inserted表,该表映射了与该触发器相连接的表的列结构。例如当用户在titles 表中插入一行时,titles表的触发器使用titles表的列结构创建inserted表,对于插入到titles表的每一行,相应的在inserted 表中也包含该行。,(2)deleted表 Deleted表也映射与该触发器相连接的表的列结构。当执行一条DELETE语句时,从表中删除的每一行都包含在删除触发器内的deleted表中。被UPDATE 语句触发的触发器创建两个表:inserted表和deleted表。这两个表和它们相连接的表有相同的列结构。deleted表和inserted表分别包含相连接表中数据的“前后”快照。例如,假设用户执行下面的Transact-SQL语句:UPDATE student SET sage=20 WHERE sage=23,当Transact-SQL语句执行时,student表中的Update触发器被触发。触发器的inserted表和deleted表中,Transact-SQL语句所改变的每一数据行都在这两个表中包含一行。Deleted表中行的数据值是执行UPDATE语句之前的student表中行的数据值;inserted表中则是执行UPDATE语句后的student表中行的数据值。触发器的使用要受到一些限制,具体如下:在一个批语句中,CREATE TRIGGER必须是第一条语句,而且它只能应用于一个表。在触发器中可以指定SET语句,SET选项在触发器执行过程中一直是有效的,在触发器执行完毕后,它会恢复原来的设置。,当触发器触发时,结果集可以返回给调用的应用程序,这就像存储过程一样。要想在触发器执行的过程中不返回结果,不要在触发器的定义中包含有返回结果的SELECT语句或包含变量赋值的语句。如果必须在触发器中使用变量的赋值,可以在触发器的开始处使用SET NOCOUNT语句,这样就不会返回结果集了。WRITETEXT语句不管是可记录的,还是不可记录的,都不能用在触发器中。,在触发器中下面的Transact-SQL语句是不能使用的:ALTER DATABASE CREATE DATABASE DISK INIT DISK RESIZE DROP DATABASE LOAD DATABASE LOAD LOG RECONFIGURE RESTORE DATABASE,7)触发器的创建的几个问题 在SQL Server中可以使用管理工具Enterprise Manager和Transac_SQL来创建触发器。创建触发器应该考虑以下几个问题:CREATE TRIGGER 语句必须是批处理中的第一个语句。创建触发器的权限默认分配给表的所有者,且不能将该权限转给其他用户。触发器为数据库对象,其名称必须遵循标识符的命名规则。虽然触发器可以引用当前数据库以外的对象,但只能在当前数据库中创建触发器。,虽然不能在临时表或系统表上创建触发器,但是触发器可以引用临时表。在含有用DELETE或UPDATE操作定义的外键的表中,不能定义INSTEAD OF和 INSTEAD OF UPDATE触发器。虽然TRUNCATE TABLE语句类似于没有WHERE子句(用于删除行)的DELETE语句,但它并不会引发DELETE触发器,因为TRUNCATE TABLE语句没有记录。WRITETEXT语句不会引发INSERT或UPDATE触发器。,当创建一个触发器时必须指定触发器名称,在哪一个表上定义触发器,触发器将何时激发,激活触发器的数据修改语句。8)创建触发器A使用企业管理器创建触发器使用企业管理器创建触发器的步骤为:展开服务器和数据库选择表节点;在右侧的面板中在要创建触发器的表上单击右键选择“所有任务”单击“管理触发器(T).”弹出如图2所示窗口。,图2 创建触发器,在名称(N)栏中选择;在文本(T)区域中输入触发器的定义;如果要检查触发器的语法可以单击检查语法按钮。B使用Transac_SQL来创建触发器 触发器是一种特殊的存储过程,它可以在用户试图在特定的表上进行特定的数据修改时自动执行。SQL Server允许对给定的INSERT、UPDATE或DELETE语句创建多个触发器。创建触发器的语法如下:,CREATE TRIGGER trigger_name ON table|view WITH ENCRYPTION FOR|AFTER|INSTEAD OF INSERT,UPDATE WITH APPEND NOT FOR REPLICATION AS IF UPDATE(column)AND|OR UPDATE(column).n|IF(COLUMNS_UPDATED()bitwise_operator updated_bitmask)comparison_operator column_bitmask.n sql_statement.n,其中各个参数的意义为:trigger_name触发器的名称。触发器名称必须符合标识符的规则。触发器在当前数据库中创建,尽管它可以引用其他数据库中的对象。限定触发器名称的所有者名字必须与ON子句中的表上的所有者名字相同。只有表的所有者才可以在该表上创建一个触发器。如果在一个名字中指定所有者,必须在另一个名字中也包括它。Table|view指定激活触发器的表或视图,它有时也称为触发表或触发视图。,WITH ENCRYPTION加密syscomments中包含CREATE TRIGGER语句的相应文本。使用WITH ENCRYPTION可以防止触发器作为SQL Server复制的一部分而被分发出去。AFTER指定只有当触发器定义中的所有操作都成功执行后,触发器才会触发。在触发器执行前所有的引用级联动作和约束检查都必须成功执行。INSTEAD OF创建一个INSTEAD OF触发器。可以为表或视图中的每一个INSERT、UPDATE或DELETE语句都指定一个INSTEAD OF触发器,也可以为在有INSTEAD OF触发器的视图上创建INSTEAD OF 触发器。,如果一个可更新的视图定义时使用了WITH CHECK OPTION选项,则INSTEAD OF触发器不允许在这个视图上定义,否则SQL Server将产生一个错误。DELETE,INSERT,UPDATE 指定触发表上的哪些数据修改语句激活该触发器。这其中必须至少指定一个选项。在触发器定义中可以使用该选项的任意组合与任意排列。如果指定了多于一个选项则必须在各选项之间用逗号隔开。对于INSTEAD OF触发器,如果表中含有指定了一个ON DELETE级联动作的引用关系,则在表上不允许使用DELETE选项。相似的情况下,也不允许使用UPDATE选项。,WITH APPEND指定在已有类型的触发器上增加一个触发器。只有当兼容性层次是65或更低的时候才要使用这个选项。如果兼容性层次是70或更高,就不需要WITH APPEND子句来为一个已有的类型增加触发器。WITH APPEND不能在INSTEAD OF触发器中使用,也不能用于AFTER触发器。该选项只能在指定了FOR的时候使用。WITH APPEND与FOR选项都是为向后兼容而设计的。它们在以后的版本中将不再使用了。NOT FOR REPLICATION指定当一个复制处理修改了触发器所在的表时,触发器不会被执行。,sql_statement 指定触发条件和触发程序动作。触发条件指定决定尝试的INSERT、DELETE或UPDATE 操作是否引起触发程序动作执行的其他基准。一条IF子句中的多个触发动作可以放在BEGIN和END之间。触发器可以包含任何数量和任何种类的Transact-SQL语句,触发器是用来基于数据修改语句检查或改变数据的,它不应该返回数据给用户,触发器中的Transact-SQL语句常包含了流控制语句。在CREATE TRIGGER语句中使用了少量特定的表inserted和deleted表。,AFTER触发器就是在某一语句(INSERT、UPDATE、DELETE)执行之后激活触发器,且只能在表上定义,可以为针对表的同一操作定义多个触发器。可以定义哪一个触发器被最先触发,哪一个被最后触发,通常使用系统过程sp_settriggerorder来完成此任务。,由删除操作激发的主表删除 AFTER 触发器示例:CREATE TRIGGER tri_stu ON student FOR DELETE ASIF rowcount=0RETURNDELETE scFROM sc t,deleted dWHERE t.sno=d.snoRETURN,INSTEAD OF触发器就是在某一语句(INSERT、UPDATE、DELETE)执行之前激活触发器,但并不执行其所定义的操作(INSERT、UPDATE、DELETE),而仅执行触发器本身。既可以在表上定义INSTEAD OF触发器,也可以在视图上定义INSTEAD OF触发器,但对同一操作只能定义一个INSTEAD OF触发器。INSTEAD OF 触发器举例:向表中插入数据时,检查学号是否存在于表中,如不存在则进行插入操作,否则就不插入,CREATE TRIGGER tri_stu1 ON student INSTEAD OF insert AS IF EXISTS(SELECT*FROM student WHERE 学 号=(SELECT 学号 FROM INSERTED)BEGIN ROLLBACK TRANSACTION PRINT 要处理记录的学号存在!END ELSE BEGIN INSERT INTO student select*from inserted PRINT 已经成功处理记录!END,由插入和修改操作激发的从表插入修改触发器示例:CREATE TRIGGER tri_sc1 ON sc FOR INSERT,UPDATE AS declare num_rows int select num_rows=rowcount IF num_rows=0 RETURN IF(select count(*)from student p,inserted I where p.sno=i.sno)!=num_rows begin raiserror 33334 试图插入/更新非法sno到sc表中!rollback transaction returnendRETURN,C.使用INSERT触发器 INSERT触发器通常被用来更新时间标记字段,或者验证被触发器监控的字段中的数据满足要求的标准,以确保数据完整性。例4:向pubs数据库的employee表插入新的记录。,USE pubsGOCREATE trigger employee_insupd ON employeeFOR insert,updateASDECLARE min_lvl tinyint,max_lvl tinyint,emp_lvl tinyint,job_id smallintSELECT min_lvl=min_lvl,max_lvl=max_lvl,emp_lvl=i.job_lvl,job_id=i.job_idFROM employee e,jobs j,inserted iwhere e.emp_id=i.emp_id and i.job_id=j.job_id,IF(job_id=1)and(emp_lvl 10)beginraiserror(job id 1 expects the default level of 10.,16,1)rollback transactionend elseIF(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 transactionend,当插入一行新数据时:INSERT employee(emp_id,fname,lname,job_id,job_lvl,pub_id)VALUES(ugv21716m,ugv,dafe,1,10,1389)由于在当前pubs数据库job表中,job_id为1的记录对应的min_lvl值为11而max_lvl 值为30,所以触发器被触发后返回如下信息:Server:Msg 50000,Level 16,State 1,Line-1074283883The level for job_id:1 should be between 11 and 30.,D.使用UPDATE触发器 修改触发器和插入触发器的工作过程基本上一致,修改一条记录等于插入了一条新的记录并且删除一条旧的记录。例5.对示例数据库pub中表employee创建UPDATE触发器。USE pubGOCREATE TRIGGER unemployee ON employeeFOR updateAS raiserror(update has been done successfully,16,10),当执行以下的更新语句时,UPDATE employee SET fname=smith WHERE emp_id=PMA42628M触发器被触发输出如下信息:Server:Msg 50000,Level 16,State 10,Procedure uemployee,Line 4update has been done successfully当执行SELECT fname FROM employee WHERE emp_id=PMA42628M语句时,输出结果如图3所示。,图3 运行结果,E.使用DELETE触发器 DELETE触发器通常用于两种情况,第一种情况是为了防止那些确实需要删除但会引起数据一致性问题的记录的删除。第二种情况是执行可删除主记录的子记录的级联删除操作。例6 当对定义了删除型触发器的pub_info表进行删除操作,首先检查要删除几行,若删除多行则返回错误信息。USE pubsGO/*建立触发器*/,CREATE TRIGGER dpub_infoON pub_info for deleteASIF(rowcount=0)RETURNIF(rowcount 1)beginrollback transactionraiserror(you can only delete one information at one time,16,1)end RETURN,/*测试触发器*/当删除一行时此触发器被触发,DELETE FROM pub_info WHERE pub_id=0736执行以下语句SELECT*FROM pub_info WHERE pub_id=0736时将输出以下信息:(所影响的行数为 0行)即该记录已被删除。,9)触发器的管理A.修改和重命名触发器(1).查看触发器使用企业管理器查看触发器信息。使用系统存储过程查看触发器。sp_help、sp_helptext和sp_depends具体用途和语法形式如下。sp_help:用于查看触发器的一般信息,如触发器的名称、属性、类型和创建时间。,sp_help 触发器名称 sp_helptext:用于查看触发器的正文信息。sp_helptext 触发器名称?sp_depends:用于查看指定触发器所引用的表或者指定的表涉及到的所有触发器。sp_depends 触发器名称 sp_depends 表名(2).修改触发器 使用企业管理器修改触发器正文。在企业管理器中,展开指定的服务器和数据库,选择指定的数据库和表,用右键单击要修改的表,,从弹出的快捷菜单中选择所有任务子菜单下的管理触发器选项,则会出现触发器属性对话框。在名称选项框中选择要修改的触发器的名称,然后在文本框中修改触发器的SQL语句,单击“检查语法”按钮,可以检查语法是否正确。使用sp_rename命令修改触发器的名称。sp_rename命令的语法形式如下:sp_rename oldname,newname使用alter trigger命令修改触发器正文。,ALTER TRIGGER命令的语法形式如下:ALTER TRIGGER trigger_name ON(table|view)WITHENCRYPTION(FOR|AFTER|INSTEAD OF)DELETE,INSERT,UPDATE NOTFORREPLICATION AS sql_statement.n|(FOR|AFTER|INSTEADOF)INSERT,UPDATE NOTFORREPLICATION AS IFUPDATE(column)AND|ORUPDATE(column).n|IF(COLUMNS_UPDATED()bitwise_operator updated_bitmask)comparison_operatorcolumn_bitmask.n sql_statement.n,(3).删除触发器 当删除一个表时,该表中包含的触发器自然也被删掉。如果只想从表中删除一个触发器,则可以使用企业管理器或DROP TRIGGER语句来删除。删除触发器所在的表时,SQL Server将会自动删除与该表相关的触发器。在企业管理器中,用右键单击要删除的触发器所在的表,从弹出的快捷菜单中选择所有任务子菜单下的管理触发器选项,则会出现触发器属性对话框。在名称选项框中选要删除的触发器,单击“删除”按钮,即可删除该触发器。,使用系统命