数据库原理及应用数据库原理及应用AnIntroductiontoDatabaseSystem数据库原理及应用数据库系统概论AnIntroductiontoDatabaseSystem第9章存储过程和触发器数据库原理及应用教学目标:•掌握存储过程和触发器的基本概念,•学会编写简单的存储过程和触发器,•对存储过程和触发器的实际应用有较好的理解。数据库原理及应用第9章存储过程和触发器•9.1存储过程•9.2触发器数据库原理及应用9.1存储过程•9.1.1存储过程的基本知识•9.1.2创建用户存储过程•9.1.3存储过程的参数数据库原理及应用9.1.1存储过程的基本知识•存储过程(StoredProcedure)是一组编译好存储在服务器上的完成特定功能T-SQL代码,是某数据库的对象。客户端应用程序可以通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行存储过程。Sp(x,y)客户:sp(1,2)数据库原理及应用9.1.1存储过程的基本知识使用存储过程而不使用存储在客户端计算机本地的T-SQL程序的优点包括:•允许标准组件式编程,增强重用性和共享性•能够实现较快的执行速度•能够减少网络流量•可被作为一种安全机制来充分利用数据库原理及应用9.1.1存储过程的基本知识在SQLServer2005中存储过程分为5类:•系统:系统提供的存储过程,sp_*,例如:sp_rename•扩展:SQLServer环境之外的动态链接库DLL,xp_•远程:远程服务器上的存储过程•用户:创建在用户数据库中的存储过程•临时:属于用户存储过程,#开头(局部:一个用户会话),##(全局:所有用户会话)数据库原理及应用9.1.2创建用户存储过程•格式:CREATEPROC过程名@形参名类型@变参名类型OUTPUTASSQL语句数据库原理及应用9.1.2创建用户存储过程例:创建一个多表查询的存储过程。USELibraryGOCREATEPROCEDUREborrowed_book1ASSELECTr.RID,r.Rname,b.BID,k.Bname,b.LendDateFROMreaderrINNERJOINborrowbONr.RID=b.RIDINNERJOINbookkONb.BID=k.BIDWHERERname='程鹏'执行存储过程:borrowed_book1或EXECborrowed_book1数据库原理及应用9.1.3存储过程的参数例:输入参数为某人的名字。USELibraryGOCREATEPROCEDUREborrowed_book2@namevarchar(10)--形式参数AsSELECTr.RID,r.Rname,b.BID,k.Bname,b.LendDateFROMreaderrINNERJOINborrowbONr.RID=b.RIDINNERJOINbookkONb.BID=k.BIDWHERERname=@nameGO直接传值:EXECborrowed_book2'程鹏'--实参表变量传值:DECLARE@temp1char(20)SET@temp1='杨树华'EXECborrowed_book2@temp1--实参表数据库原理及应用9.1.3存储过程的参数•例:使用默认参数USELibraryGOCREATEPROCEDUREborrowed_book3@namevarchar(10)=NULL--默认参数ASIF@nameISNULLSELECTr.RID,r.Rname,b.BID,k.Bname,b.LendDateFROMreaderrINNERJOINborrowbONr.RID=b.RIDINNERJOINbookkONb.BID=k.BIDELSESELECTr.RID,r.Rname,b.BID,k.Bname,b.LendDateFROMreaderrINNERJOINborrowbONr.RID=b.RIDINNERJOINbookkONb.BID=k.BIDWHERERname=@nameGO执行存储过程:EXECborrowed_book3数据库原理及应用9.1.3存储过程的参数•例:利用输出参数计算阶乘。USELibraryIFEXISTS(SELECTnameFROMsysobjectsWHEREname='factorial'ANDtype='P')DROPPROCEDUREfactorialGOCREATEPROCEDUREfactorial@infloat,--输入形式参数@outfloatOUTPUT--输出形式参数ASDECLARE@iintDECLARE@sfloatSET@i=1SET@s=1WHILE@i=@inBEGINSET@s=@s*@iSET@i=@i+1ENDSET@out=@s--给输出参数赋值调用存储过程:DECLARE@oufloatEXECfactorial5,@ouOUT--实参表PRINT@ou数据库原理及应用9.2触发器•9.2.1触发器的基本知识•9.2.2创建DML触发器•9.2.3创建DDL触发器•9.2.4修改触发器•9.2.5删除触发器•9.2.6查看触发器数据库原理及应用9.2.1触发器的基本知识•触发器是特殊的存储过程,基于一个表创建,主要作用就是实现由主键和外键所不能保证的复杂的参照完整性和数据一致性。•当触发器所保护的数据发生变化(update,insert,delete)后,自动运行以保证数据的完整性和正确性。通俗的说:通过一个动作(update,insert,delete)调用一个存储过程(触发器)。数据库原理及应用9.2.1触发器的基本知识•在数据库中发生数据操作语言(DML)事件时将启用。DML事件包括在指定表或视图中修改数据的INSERT语句、UPDATE语句或DELETE语句。DML触发器可以查询其他表,还可以包含复杂的T-SQL语句。系统将触发器和触发它的语句作为可在触发器内回滚的单个事务对待,如果检测到错误(例如,磁盘空间不足),则整个事务即自动回滚。当触发器所保护的数据发生变化(update,insert,delete)后,自动运行以保证数据的完整性和正确性。通俗的说:通过一个动作(update,insert,delete)调用一个存储过程(触发器)。数据库原理及应用9.2.1触发器的基本知识•SQLServer2005的新增功能。当服务器或数据库中发生数据定义语言(DDL)事件时将调用这些触发器。但与DML触发器不同的是,它们不会为响应针对表或视图的UPDATE、INSERT或DELETE语句而激发,相反,它们会为响应多种数据定义语言(DDL)语句而激发。这些语句主要是以CREATE、ALTER和DROP开头的语句。DDL触发器可用于管理任务,例如审核和控制数据库操作。数据库原理及应用9.2.2创建DML触发器语法格式:CREATETRIGGER触发器ON表名FOR[update,insert,delete]ASSQL语句数据库原理及应用9.2.2创建DML触发器例:创建基于表reader,DELETE操作的触发器。USELibraryGOIFEXISTS(SELECTnameFROMsysobjectsWHEREname='reader_d'ANDtype='TR')DROPTRIGGERreader_d--如果已经存在触发器reader_d则删除GOCREATETRIGGERreader_d--创建触发器ONreader--基于表FORDELETE--删除事件ASPRINT'数据被删除!'--执行显示输出GO应用:USELibraryGODELETEreaderwhereRname='aaa'数据库原理及应用9.2.2创建DML触发器例7:在表borrow中添加借阅信息记录时,得到该书的应还日期。说明:在表borrow中增加一个应还日期SReturnDate。USELibraryIFEXISTS(SELECTnameFROMsysobjectsWHEREname='T_return_date'ANDtype='TR')DROPTRIGGERT_return_dateCREATETRIGGERT_return_date--创建触发器ONBorrow--基于表borrowAfterINSERT--插入操作AS--查询插入记录INSERTED中读者的类型DECLARE@typeint,@dzbhchar(10),@tsbhchar(15)SET@dzbh=(SELECTRIDFROMinserted)SET@tsbh=(SELECTBIDFROMinserted)SELECT@type=TypeIDFROMreaderWHERERID=(SELECTRIDFROMinserted)--副本/*把Borrow表中的应还日期改为当前日期加上各类读者的借阅期限*/UPDATEBorrowSETSReturnDate=getdate()+CASEWHEN@type=1THEN90WHEN@type=2THEN60WHEN@type=3THEN30ENDWHERERID=@dzbhandBID=@tsbh应用:USELibraryINSERTINTOborrow(RID,BID)values('2000186010','TP85-08')数据库原理及应用9.2.2创建DML触发器•例:在数据库Library中,当读者还书时,实际上要修改表brorrow中相应记录还期列的值,请计算出是否过期。USELibraryIFEXISTS(SELECTnameFROMsysobjectsWHEREname='T_fine_js'ANDtype='TR')DROPTRIGGERT_fine_jsGOCREATETRIGGERT_fine_jsONborrowAfterUPDATEASDECLARE@daysint,@dzbhchar(10),@tsbhchar(15)SET@dzbh=(selectRIDfrominserted)SET@tsbh=(selectBIDfrominserted)SELECT@days=DATEDIFF(day,ReturnDate,SReturnDate)--DATEDIFF函数返回两个日期之差,单位为DAYFROMborrowWHERERID=@dzbhandBID=@tsbhIF@days0PRINT'没有过期!'ELSEPRINT'过期'+convert(char(6),@days)+'天'GO应用:USELibraryUPDATEborrowSETReturnDate='2007-12-12'WHERERID='2000186010‘andBID='TP85-08'GO数据库原理及应用9.2.2创建DML触发器例:对Library库中Reader表的DELETE操作定义触发器。USELibraryGOIFEXISTS(SELECTnameFROMsysobjectsWHEREname='reader_d'ANDtype='TR')DROPTRIGGERreader_dGOCREATETRIGGERreader_dONReaderFORDELETEASDECLARE@data_yjintSELECT@data_yj=LendnumFROMdeletedIF@data_yj0BEGINPRINT'该读者不能删除!还有'+convert(char(2),@data_yj)+'本书没还。ROLLBACKENDELSEPRINT'该读者已被删除!'GO应用:USELibraryGODELETEReaderWHERERID='2005216119'数据库原理及应用9.2.3创建DDL触发器语法形式:CREATETRIGGERtrigger_nameON{ALLSERVER|DATABASE}[WITHddl_trigger_option[,...n]]{FOR|AFTER}{ev