1、An Introduction to Database System内蒙古农业大学计算机信息工程学院内蒙古农业大学计算机信息工程学院数据库系统概论数据库系统概论An Introduction to Database System第八章第八章 存储过程存储过程本章内容本章内容n8.1 SQL Server编程结构n8.2 存储过程n8.3 触发器8.1 SQL Server编程结构编程结构n8.1.1 注释n8.1.2 批处理n8.1.3 事务n8.1.4 局部变量n8.1.5 全局变量n8.1.6 T-SQL控制语句n8.1.7 游标8.1.1 注释注释n在程序中添加注释是个很好的习惯。n什么
2、是注释:n一些说明性的文字,对代码的功能或实现方式给出简要的提示或解释。nT-SQL中注释两种方式:n/*注释语句*/n-注释语句8.1.2批处理批处理n批处理是包含一个或多个 Transact-SQL 语句的组,从应用程序一次性地发送到SQL Server执行。nSQL Server 将批处理语句编译成一个可执行单元,此单元称为执行计划。GO指令指令n用信号通知SQL Server实用工具一批 T-SQL 语句的结束。nGO 不是 Transact-SQL 语句;而是可为 osql 及 SQL Server 查询分析器识别的命令。8.1.3事务事务n什么是事务?n事务是由一系列语句(选择、插
3、入、更新或删除)构成的逻辑工作单元。如果在事务执行过程中没有遇到错误,则事务中的所有修改成为数据库的永久部分。如果遇到错误,则不对数据库做任何修改。n为什么使用事务?n维护数据库的完整性和一致性。事务的执行步骤事务的执行步骤n1.事务启动前,数据库处于一致状态。n2.应用程序发出启动事务的信号。这可以通过 BEGIN TRANSACTION 语句显式完成。或者,应用程序也可以设置在隐性事务模式下运行的选项;使新事务由前面的事务完成后所执行的第一个 Transact-SQL 语句自动启动。此时不向日志写入记录;当应用程序为数据修改生成第一个日志记录时,才向日志写入第一个记录。事务的执行步骤事务的
4、执行步骤n3.应用程序开始修改数据。一次只修改一个表中的数据。随着一系列的修改,数据库可能会处于暂时不一致的中间状态。n4.当应用程序执行到全部修改均已成功完成且数据库再次处于一致状态时,应用程序提交事务。这使全部修改成为数据库的永久部分。事务的执行步骤事务的执行步骤n5.如果应用程序遇到一些防碍事务完成的错误,则撤消或回滚所有数据修改。这将使数据库返回到事务启动前所处于的一致状态。在在SQL Server中使用事务中使用事务n有三种模式:n自动提交事务(默认模式)n显式事务n隐性事务自动提交事务自动提交事务n自动提交模式,是SQL Server的默认模式。n每个 Transact-SQL 语
5、句在完成时,都被提交或回滚;n如果一个语句成功地完成,则提交该语句;n如果遇到错误,则回滚该语句。显式事务(一)显式事务(一)n显式事务可以显式地在其中定义事务的启动和结束。nBEGIN TRANSACTIONn标志显式事务的起始点。nCOMMIT TRANSACTION n如果没有遇到错误,可使用该语句成功地结束事务。该事务中的所有数据修改在数据库中都将永久有效。事务占用的资源将被释放。nROLLBACK TRANSACTIONn用来清除遇到错误的事务。该事务修改的所有数据都返回到事务开始时的状态。事务占用的资源将被释放。显式事务(二)显式事务(二)n开始一个事务语法:BEGIN TRAN
6、SACTION transaction_name|tran_name_variablen举例:BEGIN TRAN T1UPDATE table1.INSERT INTO table2 COMMIT TRAN T1显式事务(三)显式事务(三)n提交事务语法:COMMIT TRAN SACTION transaction_name|tran_name_variable n回退事务语法:ROLLBACK TRAN SACTION transaction_name|tran_name_variable 隐性事务隐性事务n当连接以隐性事务模式进行操作时,SQL Server将在提交或回滚当前事务后自动
7、启动新事务。n无须描述事务的开始,只需提交或回滚每个事务。课堂演示(批)课堂演示(批)USE pubsGOCREATE TABLE Test1(a INT PRIMARY KEY,b CHAR(3)GOINSERT INTO Test1 VALUES(1,aaa)INSERT INTO Test1 VALUES(2,bbb)INSERT INTO Test1 VALUSE(3,ccc)/*Syntax error*/GO/*语法错误,整个批都不会被执行*/SELECT*FROM Test1 /*Returns no rows*/GO课堂演示(显式事务)课堂演示(显式事务)USE pubsGOC
8、REATE TABLE Test1(a INT PRIMARY KEY,b CHAR(3)GOBegin tranINSERT INTO Test1 VALUES(1,aaa)INSERT INTO Test1 VALUES(2,bbb)Go CommitGO课堂演示(隐性事务)课堂演示(隐性事务)n首先要更改查询分析器的设置:工具-选项-连接属性n设置implicit_transactions打上勾,确定。n插入数据INSERT INTO Test1 VALUES(1,aaa)INSERT INTO Test1 VALUES(2,bbb)Gon回退(rollback)或提交(commit)课
9、堂练习课堂练习n开始一个显示事务更新titles表,使得所有的书籍的价格增加10%,然后回退该事务,看titles表有没有变化,再次更新titles表中的价格为原来的1.1倍,这次提交事务,看表中的结果有没有变化。8.1.4局部变量局部变量n局部变量是程序的基本组成部分。n在T-SQL中怎么使用局部变量?n声明局部变量n使用局部变量声明局部变量声明局部变量n使用Declare 语句声明局部变量n语法:Declare variable_name,n使用局部变量使用局部变量n给局部变量赋值n使用Select语句n使用Set语句n语法:nSelect variablel_name=expressio
10、n From table_name,n Where clause nSet variable_name=expression,n局部变量举例(一)局部变量举例(一)n-声明一个变量nDeclare author varchar(20)n-赋值nSelect author=au_id From authors Where state=MIn-注意:这里的赋值一定要保证select语句返回的auL_id必须只有一条数据。局部变量举例(二)局部变量举例(二)n-声明变量nDeclare myvar varchar(20)rows intn-使用set赋值nSet myvar=this is a te
11、stnSet rows=(select count(*)from authors)查看变量的值查看变量的值nSelect variable_namen例如:Declare myvar varchar(20),rows intSet myvar=this is a testSet rows=(select count(*)from authors)-查看两个变量的值Select rows as rows,myvar as myvar8.1.5全局变量全局变量nSQL Server使用全局变量记录SQL Server服务器活动状态的一组数据。n介绍一些常用的全局变量nError返回最后执行的 TS
12、QL 语句的错误代码nfetch_statusncursor_rowsnrowcount课堂练习课堂练习n声明一个变量name,给这个变量赋值为pubs数据库中authors表里au_id为722-51-5454的作家姓名(au_fname+au_lname),然后查看这个变量的值是否正确。8.1.6 T-SQL控制语句控制语句nBegin End语句块nIf Else条件判断结构nWhile循环nCase多重判断结构nReturn语句Begin End语句块语句块nBegin End可以将一组SQL语句封装成一个语句块(出于编程的需要)。n任何时候当控制流语句必须执行一个包含两条或两条以上
13、T-SQL 语句的语句块时,请使用 BEGIN 和 END 语句。nBEGIN 和 END 语句必须成对使用:任何一条语句均不能单独使用。Begin End语句块举例(一)语句块举例(一)n例如,当 IF 语句仅控制一条 Transact-SQL 语句的执行时,不需要使用 BEGIN 和 END 语句:IF(ERROR 0)SET ErrorSaveVariable=ERRORn如果 ERROR 为 0,则仅跳过 SET 语句。Begin End语句块举例(二)语句块举例(二)n用 BEGIN 和 END 语句在遇到错误时做更多的事情:SET ErrorSaveVariable=ERRORIF
14、(ErrorSaveVariable 0)BEGIN ROLLBACK PRINT Error encountered,+CAST(ErrorSaveVariable AS VARCHAR(10)ENDBegin End语句块举例(三)语句块举例(三)n提示说明cast系统函数n作用:将某种数据类型的表达式显式转换为另一种数据类型。n语法:CAST(expression AS data_type)n使用演示脚本演示一段程序IF ELSE条件判断结构(一)条件判断结构(一)n在执行 T-SQL 语句时强加条件。n如果条件满足(布尔表达式返回 TRUE 时),则执行 IF 关键字后的 T-SQL
15、语句;当不满足 IF 条件时(布尔表达式返回 FALSE),就执行ELSE关键字后的T-SQL语句。IF ELSE条件判断结构(二)条件判断结构(二)n语法:IF Boolean_expression sql_statement|statement_block ELSE sql_statement|statement_block IF ELSE条件判断演示条件判断演示n如果平均价格高于15美元就显示一行语句,如果低于15美元,显示另一行语句。IF(SELECT AVG(price)FROM titles WHERE type=busniess)$15 PRINT Average title p
16、rice is less than$15.ELSE PRINT More than$15.While循环(一)循环(一)n设置重复执行 SQL 语句或语句块的条件。n只要指定的条件为真,就重复执行WHILE后面的T-SQL语句。n可以使用 BREAK 和 CONTINUE 关键字在循环内部控制 WHILE 循环中语句的执行。While循环(二)循环(二)n语法:WHILE Boolean_expression sql_statement|statement_block BREAK sql_statement|statement_block CONTINUE Case多重判断结构(一)多重判断结
17、构(一)n计算条件列表并返回多个可能结果表达式之一。nCASE 具有两种格式:n简单 CASE 函数将某个表达式与一组简单表达式进行比较以确定结果。nCASE 搜索函数计算一组布尔表达式以确定结果。Case多重判断结构(二)多重判断结构(二)n简单 CASE 函数:CASE input_expression WHEN when_expression THEN result_expression .n ELSE else_result_expression ENDCase多重判断结构(三)多重判断结构(三)nCASE 搜索函数:CASE WHEN Boolean_expression THEN
18、result_expression .n ELSE else_result_expression ENDCase多重判断结构举例多重判断结构举例n使用演示脚本演示一段程序Return语句语句n从查询或过程中无条件退出。nRETURN 即时且完全,可在任何时候用于从过程、批处理或语句块中退出,不执行位于 RETURN 之后的语句。n语法:RETURN integer_expression n除非特别指明,所有系统存储过程返回 0 值表示成功,返回非零值则表示失败。课堂练习(一)课堂练习(一)n3.查询pubs数据库的employee表,如果表中雇员的平均服务时间长于10年,则打印信息:我们的雇员
19、都很忠诚:),否则打印信息:我们的雇员经常跳槽:(。n提示:使用datediff和getdate系统函数n用法:DATEDIFF(datepart,startdate,enddate)n例如:datediff(year,hire_date,getdate()课堂练习(二)课堂练习(二)n4.查询pubs数据库中employee表,显示相关雇员信息(id,姓名,服务时间等),其中增加一个雇员类型列:如果雇佣时间不长于12年,则显示他为新雇员,否则显示他为老雇员。8.1.7游标游标nSQL Server 2000 支持的三种游标实现nTransact-SQL 游标n声明游标n打开游标n提取数据n关
20、闭游标SQL Server 2000 支持的三种游标支持的三种游标实现实现nTransact-SQL 游标(本章介绍内容)n应用编程接口(API)服务器游标n客户端游标n注意:由于 Transact-SQL 游标和 API 服务器游标都在服务器端实现,它们一起被称为服务器游标服务器游标。Transact-SQL 游标概述游标概述n基于 DECLARE CURSOR 语法,主要用在 Transact-SQL 脚本、存储过程和触发器中。nTransac-SQL 游标在服务器上实现并由从客户端发送到服务器的 Transact-SQL 语句管理。API 服务器游标概述服务器游标概述n支持 OLE DB
21、、ODBC 和 DB-Library 中的 API 游标函数。nAPI 服务器游标在服务器上实现。n每次客户应用程序调用 API 游标函数时,SQL Server OLE DB 提供程序、ODBC 驱动程序或 DB-Library 动态链接库(DLL)就把请求传送到服务器,以便对 API 服务器游标进行操作。客户端游标概述客户端游标概述n由 SQL Server ODBC 驱动程序、DB-Library DLL 和实现 ADO API 的 DLL 在内部实现。n客户端游标通过在客户端高速缓存所有结果集行来实现。n每次客户应用程序调用 API 游标函数时,SQL Server ODBC 驱动程序
22、、DB-Library DLL 或 ADO DLL 就对高速缓存在客户端中的结果集行执行游标操作。Transact-SQL 游标游标nTransact-SQL 游标主要用在存储过程、触发器和 Transact-SQL 脚本中,它们使结果集的内容对其它 Transact-SQL 语句同样可用。n使用游标有四种基本的步骤:声明游标、打开游标、提取数据、关闭游标。声明游标声明游标n象使用其它类型的变量一样,使用一个游标之前,首先应当声明它。n使用 DECLARE CURSOR 语句把 Transact-SQL 游标与一个 SELECT 语句相关联。nDECLARE CURSOR 语句同时定义游标的特
23、征,比如游标名称以及游标是否为只读或只进特性。声明游标语法声明游标语法n游标的声明包括两个部分:n游标的名称n这个游标所用到的SQL语句nSQL-92 语法DECLARE cursor_name INSENSITIVE SCROLL CURSOR FOR select_statement FOR READ ONLY|UPDATE OF column_name ,.n 声明游标的注意点(一)声明游标的注意点(一)n关于INSENSITIVE(英文意思:反应迟钝的):n使用insensitive定义的游标,把取出来的数据放入一个在tempdb数据库里创建的临时表里。n任何通过这个游标进行的操作,都
24、在这个临时表中进行。换句话说:所有对基本表的变动都不会在用这个游标进行的操作中体现出来。n声明游标时如不指定insensitive,(任何用户)对基表提交的删除和更新都反映在后面的提取中。声明游标的注意点(二)声明游标的注意点(二)n关于SCROLL:n使用scroll关键字定义的游标,具有包括如下所示的功能:FIRST,LAST,PRIOR,NEXT,RELATIVE,ABSOLUTE。n如声明游标时没有指定SCROLL关键字,那么声明的游标只有默认的NEXT功能。声明游标举例声明游标举例n声明一个包含authors表所有信息的游标DECLARE authors_cursor1 CURSOR
25、 FOR SELECT*FROM authorsn声明一个有条件限制的游标DECLARE authors_cursor2 CURSOR FOR SELECT au_id,au_fname,au_lnameFROM authorsWHERE state=UTORDER BY au_id打开游标打开游标n使用 OPEN 语句执行 SELECT 语句并生成游标。n由于打开游标是对数据库进行一些SQL SELECT的操作,它将耗费一段时间,主要取决于您使用的系统性能和这条语句的复杂程度。n语法:OPEN cursor_name|cursor_variable_name 打开游标举例打开游标举例n对于上
26、面的示例一DECLARE authors_cursor1 CURSOR FOR SELECT*FROM authorsOPEN authors_cursor1n对于上面的示例二OPEN authors_cursor2提取数据提取数据n当用OPEN语句打开了游标并在数据库中执行了查询后,您不能立即利用在查询结果集中的数据。n您必须用FETCH语句来取得数据。n一条FETCH语句一次可以将一条记录放入程序员指定的变量中。n事实上,FETCH语句是游标使用的核心。FETCH语法语法FETCH NEXT|PRIOR|FIRST|LAST|ABSOLUTE n|nvar|RELATIVE n|nvar
27、FROM cursor_name|cursor_variable_name INTO variable_name ,.n FETCH举例举例n使用演示脚本演示两段FETCH的例子n说明几点:nfetch_status:返回被 FETCH 语句执行的最后游标的状态。ncursor_rows:返回连接上最后打开的游标中当前存在的合格行的数量。关闭游标关闭游标n结束游标时,使用 CLOSE 语句关闭游标。关闭游标可以释放某些资源,但是如果重新发出一个 OPEN 语句,则该游标结构仍可用于处理。nDEALLOCATE 语句则完全释放分配给游标的资源,包括游标名称。n一般游标用完以后,使用close语句
28、关闭游标,接着使用deallocate语句释放游标。课堂练习课堂练习n5.创建一个游标,它所包含的结果集是pubs数据库中titles表中的所有书名(title)。把所有的书名以下面的格式打印出来:Title:The Busy Executives Database Guide8.2 存储过程存储过程n8.2.1 什么是存储过程n8.2.2 为什么使用存储过程n8.2.3 创建存储过程n8.2.4 使用存储过程8.2.1 存储过程引言存储过程引言n在使用SQL Server 2000 创建应用程序时,Transact-SQL 编程语言是应用程序和 SQL Server 数据库之间的主要编程接口
29、。n使用 Transact-SQL 程序时,可用两种方法存储和执行程序。n可以在本地存储程序,并创建向 SQL Server 发送命令并处理结果的应用程序;n也可以将程序在 SQL Server中存储为存储过程,并创建执行存储过程并处理结果的应用程序。8.2.2什么是存储过程什么是存储过程nTransact-SQL 语句的预编译集合,这些语句在一个名称下存储并作为一个单元进行处理。n换句话说:在一个存储过程内,可以设计、编码和测试执行某个常用任务所需的 SQL 语句和逻辑。之后,每个需要执行该任务的应用程序只须执行此存储过程即可。(代码重用)为什么使用存储过程(一)为什么使用存储过程(一)n1
30、.允许模块化程序设计n只需创建过程一次并将其存储在数据库中,以后即可在程序中调用该过程任意次。存储过程可由在数据库编程方面有专长的人员创建,并可独立于程序源代码而单独修改。n银行每个月底做结算的例子为什么使用存储过程(二)为什么使用存储过程(二)n2.对于需要重复执行的代码,执行效率更高 n如果某操作需要大量 Transact-SQL 代码或需重复执行,存储过程将比 Transact-SQL 批代码的执行要快。n系统会在创建存储过程时对其进行分析和优化,并可在首次执行该过程后使用该过程的内存中版本。n如果不采用存储过程,每次运行那些需要重复执行的 Transact-SQL 语句时,都需要把这些
31、语句从客户端发送到服务器端,并且在 SQL Server 每次执行这些语句时,都要对其进行编译和优化显然效率会很低。为什么使用存储过程(三)为什么使用存储过程(三)n3.减少网络流量n一个需要数百行 Transact-SQL 代码的操作由一条执行过程代码的单独语句就可实现,而不需要在网络中发送数百行代码。n4.可作为安全机制使用 n即使对于没有直接执行存储过程中语句的权限的用户,也可授予他们执行该存储过程的权限。存储过程的处理流程存储过程的处理流程对象信息进入对象信息进入 sysobjects 和和 syscomments系统表系统表 编译过的执行计划存放编译过的执行计划存放在缓冲区里面在缓冲
32、区里面编译编译优化优化语法分析语法分析8.2.3 创建存储过程语法创建存储过程语法CREATE PROC EDURE procedure_name parameter data_type VARYING =default OUTPUT ,.n WITH RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION AS sql_statement .n 创建存储过程举例(一)创建存储过程举例(一)n从authors表中返回所有作者的姓名、电话、地址和所在的州名。CREATE PROCEDURE au_info_allASSELECT au_lname,au_fname,p
33、hone,address,stateFROM authorsGO创建存储过程举例(二)创建存储过程举例(二)n指定参数,返回指定州的作家的姓名、电话、地址。CREATE PROCEDURE au_info state char(2)AS SELECT au_lname,au_fname,phone,addressFROM authorsWHERE state=stateGO创建存储过程举例(三)创建存储过程举例(三)n具有默认值的存储过程。CREATE PROCEDURE au_info state char(2)=CA -默认值=CAAS IF state NOT LIKE A-ZA-Z -
34、增加一段检查代码 BEGIN print 输入参数错误 return ENDSELECT au_lname,au_fname,phone,addressFROM authorsWHERE state=stateGO8.2.4使用存储过程(一)使用存储过程(一)n对于例1我们可以以下面的方式执行:nEXECUTE au_info_allnEXEC au_info_alln如果该过程是批处理中的第一条语句,则可使用:au_info_all使用存储过程(二)使用存储过程(二)n对于例2(有参数的存储过程)我们可以以下面的方式执行:nEXECUTE au_info CAnEXECUTE au_info
35、 state=CAnEXEC au_info CAnEXEC au_info state=CAn如果该过程是批处理中的第一条语句,则可使用:nau_info CAnau_info state=CA使用存储过程(三)使用存储过程(三)n对于例3(有默认值的存储过程)我们可以以下面的方式执行:n同例2,指定参数n不指定参数,使用默认参数:nEXECUTE au_infonEXEC au_infon如果该过程是批处理中的第一条语句,则可使用:au_info使用使用Output参数返回结果参数返回结果CREATE PROCEDURE MathTutor m1 smallint,m2 smallint,
36、result smallint OUTPUTAS SET result=m1*m2GODECLARE answer smallintEXECUTE MathTutor 5,6,answer OUTPUTSELECT The result is:,answerThe result is:30课堂练习课堂练习n6.创建一个存储过程,显示所有价格在15美元以下的书的书名,类型,价格。n7.把价格作为参数,创建一个能显示在某两个指定价格之间的书的书名,类型,价格。n8.使用OUTPUT参数,创建一个计算圆柱体体积的存储过程。并执行它。8.3触发器触发器n8.3.1触发器概述n8.3.2触发器的功能n8
37、.3.3创建触发器n8.3.4Inserted和deleted表n8.3.5建立列级触发器n8.3.6使用 INSTEAD OF 触发器n8.3.7使用触发器的注意点8.3.1触发器概述触发器概述n触发器是一类特殊的存储过程,被定义为在对表或视图发出 UPDATE、INSERT 或 DELETE 语句时自动执行。n触发器是与表紧密相连,是与某个表关联的。也就是说,如果在这个表上发生了UPDATE、INSERT 或 DELETE 操作,就会触发相应的触发器进行工作。8.3.2触发器分类触发器分类nAFTER触发器n触发器在触发它们的语句完成后执行。n如果该语句因错误(如违反约束或语法错误)而失败
38、,触发器将不会执行。n不能为视图指定 AFTER 触发器。n在 SQL Server 2000 中 AFTER 是默认触发器。nINSTEAD OF触发器n该触发器代替触发操作执行。n可在表和视图上指定 INSTEAD OF 触发器。n只能为每个触发操作(INSERT、UPDATE 和 DELETE)定义一个 INSTEAD OF 触发器。8.3.3触发器的功能触发器的功能n触发器可通过数据库中的相关表实现级联更改;不过,通过级联引用完整性约束可以更有效地执行这些更改;n执行比check约束更复杂的商业逻辑;n查找在数据修改前后,表状态之间的差别,并根据差别采取相应的措施;n一个表中的多个同类
39、触发器(INSERT、UPDATE 或 DELETE)允许采取多个不同的对策以响应同一个修改语句。8.3.4创建触发器语法创建触发器语法CREATE TRIGGER trigger_name ON table|view WITH ENCRYPTION FOR|AFTER|INSTEAD OF INSERT,DELETE,UPDATE AS sql_statement 创建触发器举例(一)创建触发器举例(一)CREATE TRIGGER reminderON authorsFOR UPDATE AS declare rowcount varchar(10)set rowcount=cast(ro
40、wcount as varchar(10)print rowcount+data updated!GOupdate authors set au_lname=haijian where au_fname=zhang8.3.5 Inserted和和deleted表表n触发器语句中使用了两种特殊的表:deleted 表和 inserted 表。n这两张表存储在高速缓存中,SQL Server 自动创建和管理这两个表。n这两个表的结构和与当前触发器所关联的表的结构一样。n可以使用这两个临时的驻留内存的表测试某些数据修改的效果及设置触发器操作的条件;n只有在触发器中才可以使用这两个表,且不能直接对表中
41、的数据进行更改。创建触发器举例(二)创建触发器举例(二)CREATE TRIGGER reminderON authorsFOR UPDATE AS declare old_lname varchar(20),new_lname varchar(20)select old_lname=au_lname from deleted select new_lname=au_lname from insertedprint old lname is:+old_lname+,new lname is:+new_lnameselect*from deletedselect*from insertedHow
42、 an INSERT Trigger WorksINSERT statement to a table with an INSERT Trigger DefinedINSERT Order Details VALUES(10525,2,19.00,5,0.2)OrderID105221052310524ProductID10417UnitPrice31.009.6530.00Quantity7924Discount0.20.150.0 5 19.002 0.210523Insert statement logged10523219.0050.2TRIGGER Actions ExecuteOr
43、derID105221052310524ProductID10417UnitPrice31.009.6530.00Quantity7924Discount0.20.150.0 5 19.002 0.210523Trigger Code:USE NorthwindCREATE TRIGGER OrdDet_InsertON Order DetailsFOR INSERTASUPDATE P SET UnitsInStock=(P.UnitsInStock I.Quantity)FROM Products AS P INNER JOIN Inserted AS ION P.ProductID=I.
44、ProductIDUPDATE P SET UnitsInStock=(P.UnitsInStock I.Quantity)FROM Products AS P INNER JOIN Inserted AS ION P.ProductID=I.ProductIDProductID UnitsInStock 123415106520215INSERT Statement to a Table with an INSERTTrigger DefinedINSERT Statement LoggedTrigger Actions ExecutedHow a DELETE Trigger WorksD
45、ELETE Statement to a table with a DELETE Trigger DefinedDELETE Statement to a table with a DELETE Trigger Defined4Dairy ProductsCheeses0 x15DELETE statement loggedCategoryID123CategoryNameBeveragesCondimentsConfectionsDescriptionSoft drinks,coffeesSweet and savory Desserts,candies,Picture0 x150 x150
46、 x15 0 x15CheesesDairy Products4DELETE CategoriesWHERE CategoryID=4USE NorthwindCREATE TRIGGER Category_DeleteON CategoriesFOR DELETEASUPDATE P SET Discontinued=1FROM Products AS P INNER JOIN deleted AS dON P.CategoryID=d.CategoryIDProductID Discontinued 12340000Trigger Actions Execute2 1UPDATE P SE
47、T Discontinued=1FROM Products AS P INNER JOIN deleted AS dON P.CategoryID=d.CategoryIDDELETE Statement to a Table with a DELETEStatement DefinedDELETE Statement LoggedTrigger Actions ExecutedHow an UPDATE Trigger WorksUPDATE Statement to a table with an UPDATE Trigger DefinedUPDATE EmployeesSET Empl
48、oyeeID=17WHERE EmployeeID=2UPDATE Statement logged as INSERT and DELETE StatementsEmployeeID LastName FirstNameTitleHireDate1234DavolioBarrLeverlingPeacockNancyAndrewJanetMargaretSales Rep.RSales Rep.Sales Rep.2FullerAndrew Vice Pres.17FullerAndrew Vice Pres.2FullerAndrew Vice Pres.TRIGGER Actions E
49、xecuteUSE NorthwindGOCREATE TRIGGER Employee_UpdateON EmployeesFOR UPDATEASIF UPDATE(EmployeeID)BEGIN TRANSACTIONRAISERROR(Transaction cannot be processed.*Employee ID number cannot be modified.,10,1)ROLLBACK TRANSACTIONASIF UPDATE(EmployeeID)BEGIN TRANSACTIONRAISERROR(Transaction cannot be processe
50、d.*Employee ID number cannot be modified.,10,1)ROLLBACK TRANSACTION Transaction cannot be processed.*Member number cannot be modifiedEmployeeID LastName FirstNameTitleHireDate1234DavolioBarrLeverlingPeacockNancyAndrewJanetMargaretSales Rep.RSales Rep.Sales Rep.2FullerAndrew Vice Pres.UPDATE Statemen