MySQL數(shù)據(jù)庫(kù)應(yīng)用教程 課件 第9、10章 存儲(chǔ)過(guò)程、異常處理和游標(biāo);觸發(fā)器和事件_第1頁(yè)
MySQL數(shù)據(jù)庫(kù)應(yīng)用教程 課件 第9、10章 存儲(chǔ)過(guò)程、異常處理和游標(biāo);觸發(fā)器和事件_第2頁(yè)
MySQL數(shù)據(jù)庫(kù)應(yīng)用教程 課件 第9、10章 存儲(chǔ)過(guò)程、異常處理和游標(biāo);觸發(fā)器和事件_第3頁(yè)
MySQL數(shù)據(jù)庫(kù)應(yīng)用教程 課件 第9、10章 存儲(chǔ)過(guò)程、異常處理和游標(biāo);觸發(fā)器和事件_第4頁(yè)
MySQL數(shù)據(jù)庫(kù)應(yīng)用教程 課件 第9、10章 存儲(chǔ)過(guò)程、異常處理和游標(biāo);觸發(fā)器和事件_第5頁(yè)
已閱讀5頁(yè),還剩125頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第9章存儲(chǔ)過(guò)程、異常處理和游標(biāo)《MySQL數(shù)據(jù)庫(kù)應(yīng)用教程》劉瑞新主編配套資源目錄第9章存儲(chǔ)過(guò)程、異常處理和游標(biāo)9.1存儲(chǔ)過(guò)程9.2異常處理9.3使用游標(biāo)處理結(jié)果集9.1.1存儲(chǔ)過(guò)程的概念9.1.2創(chuàng)建存儲(chǔ)過(guò)程CREATEPROCEDUREsp_name([proc_parameter1,proc_parameter2,…])[characteristic…]routine_body;9.1存儲(chǔ)過(guò)程【例9-1】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建一個(gè)顯示student表中所有記錄的存儲(chǔ)過(guò)程。CREATEPROCEDUREproc_display_all_student()READSSQLDATABEGINSELECT*FROMstudent;END;9.1存儲(chǔ)過(guò)程9.1存儲(chǔ)過(guò)程9.1.3執(zhí)行存儲(chǔ)過(guò)程CALL[db_name.]sp_name([parameter1,parameter2,…]);【例9-2】執(zhí)行proc_display_all_student過(guò)程。執(zhí)行存儲(chǔ)過(guò)程的SQL語(yǔ)句如下:CALLproc_display_all_student();9.1存儲(chǔ)過(guò)程9.1.4創(chuàng)建存儲(chǔ)過(guò)程的步驟1.實(shí)現(xiàn)存儲(chǔ)過(guò)程的功能【例9-3】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建不帶參數(shù)的存儲(chǔ)過(guò)程proc_selectcourse_avg,顯示selectcourse表中的學(xué)號(hào)和每位學(xué)生的平均成績(jī)。編寫(xiě)下面語(yǔ)句,SQL語(yǔ)句如下:SELECTstudentID,avg(Score)平均分

FROMselectcourseGROUPBYStudentID;9.1存儲(chǔ)過(guò)程2.創(chuàng)建存儲(chǔ)過(guò)程CREATEPROCEDUREproc_selectcourse_avg()READSSQLDATACOMMENT'顯示學(xué)號(hào)和每位學(xué)生的平均成績(jī)'BEGINSELECTstudentID,avg(Score)平均分FROMselectcourseGROUPBYStudentID;END;9.1存儲(chǔ)過(guò)程3.執(zhí)行存儲(chǔ)過(guò)程CALLproc_selectcourse_avg();9.1存儲(chǔ)過(guò)程9.1.5存儲(chǔ)過(guò)程的管理1.查看存儲(chǔ)過(guò)程的狀態(tài)和定義(1)查看存儲(chǔ)過(guò)程的狀態(tài)SHOWPROCEDURESTATUS[LIKE'pattern'];例如,SQL語(yǔ)句如下:SHOWPROCEDURESTATUSLIKE'pro%';9.1存儲(chǔ)過(guò)程(2)查看存儲(chǔ)過(guò)程的定義SHOWCREATEPROCEDUREsp_name;例如,SQL語(yǔ)句如下:SHOWCREATEPROCEDUREproc_display_all_student;9.1存儲(chǔ)過(guò)程(3)查看所有的存儲(chǔ)過(guò)程SELECT*FROMinformation_schema.routines[WHEREroutine_name='名稱(chēng)'];例如SELECT*FROMinformation_schema.routines;SELECT*FROMinformation_schema.routinesWHEREroutine_name='proc_display_all_student';9.1存儲(chǔ)過(guò)程2.修改存儲(chǔ)過(guò)程ALTERPROCEDUREsp_name[characteristic…]【例9-4】修改存儲(chǔ)過(guò)程up_display_all_student的定義,將特性改為MODIFIESSQLDATA,并指明權(quán)限調(diào)用者可以執(zhí)行。ALTERPROCEDUREproc_display_all_studentMODIFIESSQLDATASQLSECURITYINVOKER;9.1存儲(chǔ)過(guò)程3.刪除存儲(chǔ)過(guò)程DROPPROCEDURE[IFEXISTS]sp_name;【例9-5】刪除存儲(chǔ)過(guò)程proc_display_all_student。SQL語(yǔ)句如下:DROPPROCEDUREIFEXISTSproc_display_all_student;9.1存儲(chǔ)過(guò)程3.使用Navicat管理存儲(chǔ)過(guò)程9.1存儲(chǔ)過(guò)程9.1.6存儲(chǔ)過(guò)程的各種參數(shù)應(yīng)用1.不帶參數(shù)的存儲(chǔ)過(guò)程(1)創(chuàng)建不帶參數(shù)的存儲(chǔ)過(guò)程CREATEPROCEDUREsp_name()[characteristic…]routine_body;9.1存儲(chǔ)過(guò)程(2)執(zhí)行不帶參數(shù)的存儲(chǔ)過(guò)程執(zhí)行不帶參數(shù)的存儲(chǔ)過(guò)程的語(yǔ)法格式為:CALLsp_name();9.1存儲(chǔ)過(guò)程【例9-6】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建不帶參數(shù)的存儲(chǔ)過(guò)程proc_student_age,查詢(xún)學(xué)生表student中的全體學(xué)生,顯示姓名、性別和年齡。CREATEPROCEDUREproc_student_age()READSSQLDATACOMMENT'查詢(xún)學(xué)生表student中的全體學(xué)生,顯示姓名、性別和年齡'BEGINSELECTStudentNameAS姓名,SexAS性別,YEAR(NOW())-YEAR(Birthday)AS年齡

FROMstudent;END;CALLproc_student_age();9.1存儲(chǔ)過(guò)程2.帶IN參數(shù)的存儲(chǔ)過(guò)程CREATEPROCEDUREsp_name(INparam_name1type1[,INparam_name2type2,…])[characteristic…]routine_body;在執(zhí)行調(diào)用存儲(chǔ)過(guò)程時(shí),實(shí)參要給出具體的值。執(zhí)行帶IN參數(shù)的存儲(chǔ)過(guò)程的語(yǔ)法格式為:CALLsp_name(parameter1[,parameter2,…]);9.1存儲(chǔ)過(guò)程【例9-7】創(chuàng)建帶有輸入?yún)?shù)的存儲(chǔ)過(guò)程proc_student_class,給定班級(jí)編號(hào),查詢(xún)出該班級(jí)的所有學(xué)生記錄。1)CREATEPROCEDUREproc_student_class(INvClassIDCHAR(10))READSSQLDATABEGINSELECT*FROMstudentWHEREClassID=vClassID;END;2)CALLproc_student_class('2022600103');或SET@ClassID='2022600103';CALLproc_student_class(@ClassID);9.1存儲(chǔ)過(guò)程3.帶OUT參數(shù)的存儲(chǔ)過(guò)程CREATEPROCEDUREsp_name(INparam_name1type1[,…],OUTparam_name2type2[,…])[characteristic…]routine_body執(zhí)行帶OUT參數(shù)的存儲(chǔ)過(guò)程的語(yǔ)法格式為:SET@variable_name=表達(dá)式;CALLsp_name(parameter1[,…],@variable_name[,…]);9.1存儲(chǔ)過(guò)程【例9-8】創(chuàng)建帶有輸入?yún)?shù)和輸出參數(shù)的存儲(chǔ)過(guò)程proc_selectcourse,給定學(xué)號(hào),查詢(xún)出該學(xué)生選修課程的數(shù)量和平均分,并通過(guò)輸出參數(shù)返回。1)CREATEPROCEDUREproc_selectcourse(INvStudentIDCHAR(12),OUTvCountCourseINT,OUTvAvgScoreFLOAT)READSSQLDATABEGINSELECTCOUNT(CourseID)INTOvCountCourseFROMselectcourseWHEREStudentID=vStudentID;SELECTAVG(Score)INTOvAvgScoreFROMselectcourseWHEREStudentID=vStudentID;END;9.1存儲(chǔ)過(guò)程2)SQL語(yǔ)句如下:CALLproc_selectcourse('202263050132',@CountCourse,@AvgScore);SQL語(yǔ)句如下:SET@StudentID='202263050132',@CountCourse=NULL,@AvgScore=NULL;CALLproc_selectcourse(@StudentID,@CountCourse,@AvgScore);SQL語(yǔ)句如下:SELECT@CountCourse,@AvgScore;9.1存儲(chǔ)過(guò)程9.1存儲(chǔ)過(guò)程【例9-9】創(chuàng)建帶有輸入?yún)?shù)和輸出參數(shù)的存儲(chǔ)過(guò)程proc_getscores,給定學(xué)號(hào),統(tǒng)計(jì)該學(xué)生的考試課程數(shù)和合格的課程數(shù),并通過(guò)輸出參數(shù)返回。1)CREATEPROCEDUREproc_getscores(INvStudentIDCHAR(12),OUTvCountCourseINT,OUTvCountCoursesPassINT)READSSQLDATABEGINSELECTCOUNT(CourseID)INTOvCountCourseFROMselectcourseWHEREStudentID=vStudentID;SELECTCOUNT(CourseID)INTOvCountCoursesPassFROMselectcourseWHEREStudentID=vStudentIDANDScore>=60;END;9.1存儲(chǔ)過(guò)程2)SET@StudentID='202263050132',@CountCourse=NULL,@CountCoursePass=NULL;CALLproc_getscores(@StudentID,@CountCourse,@CountCoursePass);SELECT@CountCourseAS考試課程數(shù),@CountCoursePassAS合格的課程數(shù);9.1存儲(chǔ)過(guò)程【例9-10】創(chuàng)建存儲(chǔ)過(guò)程proc_query_score,傳入學(xué)號(hào),顯示該學(xué)號(hào)學(xué)生的成績(jī),如果全部成績(jī)>=60,則返回“Allpasses”;否則返回通過(guò)的課程門(mén)數(shù)和不通過(guò)的課程門(mén)數(shù)。CREATEPROCEDUREproc_query_score(INst_idCHAR(12),OUTstrCHAR(30))BEGINDECLAREpass,notpassTINYINTDEFAULT0;SELECTCOUNT(*)INTOpassFROMselectcourseWHEREStudentID=st_idANDScore>=60;SELECTCOUNT(*)INTOnotpassFROMselectcourseWHEREStudentID=st_idANDScore<60;IFnotpass=0THENBEGINSETstr='Allpasses';END;ELSEBEGINSETstr=CONCAT('Pass:',CONVERT(pass,CHAR(2)),'Notpass:',CONVERT(notpass,CHAR(2)));END;ENDIF;SELECT*FROMselectcourseWHEREStudentID=st_id;END;9.1存儲(chǔ)過(guò)程CALLproc_query_score('202263050132',@str);

SELECT@str;

CALLproc_query_score('202263050133',@str);

SELECT@str;9.1存儲(chǔ)過(guò)程4.帶INOUT參數(shù)的存儲(chǔ)過(guò)程CREATEPROCEDUREsp_name(INOUTparam_nametype[,…])[characteristic…]routine_body;SET@variable_name=表達(dá)式;CALLsp_name(@variable_name[,…]);9.1存儲(chǔ)過(guò)程【例9-11】創(chuàng)建帶有INOUT參數(shù)的存儲(chǔ)過(guò)程proc_ispass,給定學(xué)號(hào)、課程號(hào),查詢(xún)得到對(duì)應(yīng)的成績(jī)?nèi)绻笥诨虻扔?0,則為1,否則為0,通過(guò)INOUT參數(shù)返回該值。CREATEPROCEDUREproc_ispass(INvStudentIDCHAR(12),INvCourseIDCHAR(10),INOUTpassINT)READSSQLDATABEGINDECLAREvScoreFLOAT;SELECTScoreINTOvScoreFROMselectcourseWHEREStudentID=vStudentIDANDCourseID=vCourseID;IFvScore>=60THENSETpass=1;ELSESETpass=0;ENDIF;END;9.1存儲(chǔ)過(guò)程2)調(diào)用存儲(chǔ)過(guò)程proc_ispass,INOUT參數(shù)保存在@pass中。SQL語(yǔ)句如下:SET@pass=0;CALLproc_ispass('202263050132','630575',@pass);SELECT@pass;9.1存儲(chǔ)過(guò)程9.2.1自定義異常名稱(chēng)語(yǔ)句DECLAREcondition_nameCONDITIONFORcondition_value;SQLSTATEsqlstate_value|mysql_error_code;【例9-12】用名字定義“1062(23000)”這個(gè)錯(cuò)誤,名稱(chēng)為error_insert??梢杂脙煞N不同的方法定義。方法一:使用sqlstate_value,SQL語(yǔ)句如下:DECLAREerror_insertCONDITIONFORSQLSTATE'23000';方法二:使用mysql_error_code,SQL語(yǔ)句如下:DECLAREerror_insertCONDITIONFOR1062;9.2異常處理9.2.2自定義異常處理程序DECLAREhandler_typeHANDLERFORcondition_valuesp_statement;condition_name|mysql_error_code|SQLSTATEsqlstate_value|SQLWARNING|NOTFOUND|SQLEXCEPTION9.2異常處理9.2.3異常處理實(shí)例【例9-13】在studentinfo數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)表users,該表的u_id列為主鍵,當(dāng)插入相同的主鍵值時(shí)觸發(fā)異常。1)USEstudentinfo;DROPTABLEIFEXISTSusers;CREATETABLEusers(u_idINTPRIMARYKEY,u_nameCHAR(10));2)DROPPROCEDUREIFEXISTSproc_insert_userCREATEPROCEDUREproc_insert_user(INuidINT,INunameCHAR(10),OUTinfoCHAR(20))MODIFIESSQLDATABEGININSERTINTOusers(u_id,u_name)VALUES(uid,uname);SETinfo='Insertcomplete'; END;9.2異常處理3)調(diào)用存儲(chǔ)過(guò)程。①CALLproc_insert_user(123,'Jack',@info);

SELECT*FROMusers;9.2異常處理②CALLproc_insert_user(123,'Lily',@info);

SELECT@info;9.2異常處理4)DROPPROCEDUREIFEXISTSproc_insert_user1;CREATEPROCEDUREproc_insert_user1(INuidINT,INunameCHAR(10),OUTinfoCHAR(20))MODIFIESSQLDATABEGIN#方式1DECLAREerror1CONDITIONFOR1062;

DECLAREEXITHANDLERFORerror1SETinfo='Cannotinsert';

#方式2#DECLAREEXITHANDLERFOR1062SETinfo='Cannotinsert';INSERTINTOusers(u_id,u_name)VALUES(uid,uname);SETinfo='Insertcomplete';END;9.2異常處理3)調(diào)用存儲(chǔ)過(guò)程。①CALLproc_insert_user1(301,'Lily',@info);

SELECT*FROMusers;9.2異常處理②CALLproc_insert_user1(301,'Alex',@info);

SELECT@info;

SELECT*FROMusers;9.2異常處理9.3.1游標(biāo)的概念9.3.2定義游標(biāo)DECLAREcursor_nameCURSORFORselect_statement;9.3使用游標(biāo)處理結(jié)果集【例9-14】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建一個(gè)游標(biāo),從student表中查詢(xún)出學(xué)號(hào)、姓名和班級(jí)號(hào)列的記錄。DECLAREcur_studentCURSORFORSELECTStudentID,StudentName,BirthdayFROMstudent;SELECTStudentID,StudentName,BirthdayFROMstudent;9.3使用游標(biāo)處理結(jié)果集9.3.3打開(kāi)游標(biāo)OPENcursor_name;例如,打開(kāi)前面例題創(chuàng)建的cur_student游標(biāo),SQL語(yǔ)句如下:OPENcur_student;9.3使用游標(biāo)處理結(jié)果集9.3.4使用游標(biāo)FETCHcursor_nameINTOvar_name1[,var_name2,…];9.3使用游標(biāo)處理結(jié)果集終止游標(biāo)執(zhí)行:DECLAREdoneBOOLEANDEFAULT0; --DECLAREdoneINTDEFAULTFALSE;DECLAREcurCURSORFORSELECT…;DECLARECONTINUEHANDLERFORNOTFOUNDSETdone=1;--DECLARECONTINUEHANDLERFORSQLSTATE'02000'SETdone=1;--DECLARECONTINUEHANDLERFORNOTFOUNDSETdone=TRUE;9.3使用游標(biāo)處理結(jié)果集遍歷游標(biāo)第1種使用WHILE循環(huán)。OPENcur;FETCHcurINTO…;WHILE(done!=1)DO #WHILE(NOTdone)DO#處理語(yǔ)句;FETCHcurINTO…;ENDWHILE;CLOSEcur; #關(guān)閉游標(biāo)9.3使用游標(biāo)處理結(jié)果集第2種使用REPEAT循環(huán)。OPENcur;REPEATFETCHcurINTO…;IFdone!=1THEN #IF(NOTdone)THEN#處理語(yǔ)句;ENDIF;UNTILdoneENDREPEAT;CLOSEcur; #關(guān)閉游標(biāo)9.3使用游標(biāo)處理結(jié)果集9.3.5關(guān)閉游標(biāo)CLOSEcursor_name;9.3使用游標(biāo)處理結(jié)果集9.3.6游標(biāo)的應(yīng)用【例9-15】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建存儲(chǔ)過(guò)程up_cur_student,用游標(biāo)獲取student表中北京籍學(xué)生的學(xué)號(hào)、姓名和出生日期。1)創(chuàng)建存儲(chǔ)過(guò)程up_cur_student,SQL語(yǔ)句如下:DROPPROCEDUREIFEXISTSproc_cur_student;CREATEPROCEDUREproc_cur_student()READSSQLDATABEGIN#定義接收游標(biāo)數(shù)據(jù)的變量DECLAREvIDCHAR(12);DECLAREvNameVARCHAR(20);DECLAREvBirthdayDATE;DECLAREdoneBOOLEANDEFAULT0; #定義結(jié)束循環(huán)的標(biāo)志變量9.3使用游標(biāo)處理結(jié)果集#定義游標(biāo)DECLAREcur_stCURSORFORSELECTStudentID,StudentName,BirthdayFROMstudentWHEREAddress='北京';DECLARECONTINUEHANDLERFORNOTFOUNDSETdone=1;OPENcur_st; #打開(kāi)游標(biāo)#開(kāi)始循環(huán)游標(biāo)中的記錄REPEATFETCHcur_stINTOvID,vName,vBirthday;#游標(biāo)指針指向一條記錄

IFdone!=1THEN #判斷游標(biāo)的循環(huán)是否結(jié)束

SELECTvID,vName,vBirthday;ENDIF;UNTILdoneENDREPEAT;CLOSEcur_st; #關(guān)閉游標(biāo)END;9.3使用游標(biāo)處理結(jié)果集DECLARECONTINUEHANDLERFORNOTFOUNDSETdone=1;2)執(zhí)行存儲(chǔ)過(guò)程,SQL語(yǔ)句如下:CALLproc_cur_student();9.3使用游標(biāo)處理結(jié)果集【例9-16】用游標(biāo)計(jì)算student表中的男生數(shù),此功能可以直接使用COUNT()函數(shù),此例為演示游標(biāo)的使用方法。CREATEPROCEDUREproc_cur_sum(OUTsumINT)BEGINDECLAREvSexCHAR(20); #定義接收游標(biāo)數(shù)據(jù)的變量DECLAREdoneINTDEFAULT0; #定義結(jié)束循環(huán)的標(biāo)志變量DECLAREcurCURSORFORSELECTSexFROMstudentWHERESex='男';DECLARECONTINUEHANDLERFORSQLSTATE'02000'SETdone=1;SETsum=0; #計(jì)算人數(shù)的初始值OPENcur; #打開(kāi)游標(biāo)ww:LOOPFETCHcurINTOvSex; #使用游標(biāo),游標(biāo)指針指向第1條記錄

#如果發(fā)生異常

IFdone=1THENLEAVEww;ENDIF;IFvSex='男'THENSETsum=sum+1;

ENDIF;ENDLOOP;CLOSEcur;END; 9.3使用游標(biāo)處理結(jié)果集2)執(zhí)行存儲(chǔ)過(guò)程CALLproc_cur_count,SQL語(yǔ)句如下:CALLproc_cur_sum(@n);SELECT@nAS男生數(shù);9.3使用游標(biāo)處理結(jié)果集祝賀你完成了最難的一章《MySQL數(shù)據(jù)庫(kù)應(yīng)用教程》劉瑞新主編配套資源第10章觸發(fā)器和事件《MySQL數(shù)據(jù)庫(kù)應(yīng)用教程》劉瑞新主編配套資源目錄第10章觸發(fā)器和事件10.1觸發(fā)器10.2事件10.1.1觸發(fā)器的基本概念1.觸發(fā)器概念2.觸發(fā)器的分類(lèi)3.觸發(fā)器的特點(diǎn)10.1觸發(fā)器10.1.2創(chuàng)建觸發(fā)器CREATETRIGGERtrigger_name{BEFORE|AFTER}{INSERT|UPDATE|DELETE}ONtable_nameFOREACHROW[trigger_order]trigger_body;10.1觸發(fā)器【例10-1】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建一個(gè)觸發(fā)器tr_student_insert_sex,當(dāng)向student表中插入記錄時(shí),檢查性別是否為“男”或“女”,如果不是,則設(shè)置為“男”。1)創(chuàng)建觸發(fā)器。#DROPTRIGGERIFEXISTStr_student_insert_sex;CREATETRIGGERtr_student_insert_sexBEFOREINSERTONstudentFOREACHROWBEGINIFNEW.Sex!='男'&&NEW.Sex!='女'THENSETNEW.Sex='男';ENDIF;END;10.1觸發(fā)器2)測(cè)試觸發(fā)器。①I(mǎi)NSERTINTOstudent(StudentID,StudentName,Sex,Birthday,Address,ClassID)VALUES('202270010121','吳琪妙','F','2003-04-11','陜西','2022700101');

10.1觸發(fā)器②SELECT*FROMstudentWHEREStudentID='202270010121';

10.1觸發(fā)器10.1.3觸發(fā)程序中的NEW和OLD1.OLD關(guān)鍵字與NEW關(guān)鍵字的方式(1)INSERT型觸發(fā)器(2)DELETE型觸發(fā)器(3)UPDATE型觸發(fā)器10.1觸發(fā)器2.訪問(wèn)觸發(fā)器NEW和OLD表的語(yǔ)法訪問(wèn)觸發(fā)器NEW和OLD表的語(yǔ)法格式為:OLD.column_nameNEW.column_name10.1觸發(fā)器【例10-2】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建一個(gè)觸發(fā)器tr_student_insert_classnum,當(dāng)向student表中插入記錄時(shí),自動(dòng)更新class表中的班級(jí)人數(shù)。1)創(chuàng)建觸發(fā)器。#DROPTRIGGERIFEXISTStr_student_insert_classnumCREATETRIGGERtr_student_insert_classnumAFTERINSERTONstudentFOREACHROWBEGINDECLAREnINTDEFAULT0; #保存插入記錄前的班級(jí)人數(shù)

#取出班級(jí)表中保存的班級(jí)人數(shù)

SETn=(SELECTClassNumFROMclassWHEREClassID=NEW.ClassID);UPDATEclassSETClassNum=n+1WHEREClassID=NEW.ClassID;END;10.1觸發(fā)器2)測(cè)試觸發(fā)器。

UPDATEclassSETClassNum=30WHEREClassID='2022700101';#給該班人數(shù)設(shè)置一個(gè)初始值SELECT*FROMclassWHEREClassID='2022700101';

INSERTINTOstudent(StudentID,StudentName,Sex,Birthday,Address,ClassID)VALUES('202270010166','張蕊','女','2003-05-08','河北','2022700101');

SELECT*FROMclassWHEREClassID='2022700101';

10.1觸發(fā)器10.1.4查看觸發(fā)器1.使用SHOWTRIGGERS語(yǔ)句查看觸發(fā)器信息SHOWTRIGGERS[{FROM|IN}db_name];【例10-3】查看數(shù)據(jù)庫(kù)studentinfo中已有的觸發(fā)器的狀態(tài)等信息。USEstudentinfo;SHOWTRIGGERS;10.1觸發(fā)器2.在triggers表中查看觸發(fā)器詳細(xì)信息SELECT*FROMinformation_schema.triggers[WHERETRIGGER_NAME='trigger_name'];【例10-4】使用SELECT語(yǔ)句查詢(xún)triggers表中的信息。1)SELECT*FROMinformation_schema.triggers;10.1觸發(fā)器2)SELECT*FROMinformation_schema.triggersWHERETRIGGER_NAME='tr_student_insert';10.1觸發(fā)器10.1.5刪除觸發(fā)器DROPTRIGGER[IFEXISTS][schema_name.]trigger_name;【例10-5】刪除數(shù)據(jù)庫(kù)studentinfo中的觸發(fā)器。DROPTRIGGERIFEXISTStr_student_insert_sex;DROPTRIGGERIFEXISTStr_student_insert_classnum;DROPTRIGGERIFEXISTSstudentinfo.tr_student_insert;10.1觸發(fā)器10.3.6觸發(fā)器的類(lèi)型和執(zhí)行順序1.觸發(fā)器的類(lèi)型(1)INSERT觸發(fā)器(2)DELETE觸發(fā)器(3)UPDATE觸發(fā)器10.1觸發(fā)器2.觸發(fā)器的6種形式1)BEFOREINSERT2)AFTERINSERT3)BEFOREDELETE4)AFTERDELETE5)BEFOREUPDATE6)AFTERINSERT10.1觸發(fā)器3.觸發(fā)器的執(zhí)行順序【例10-6】在T_reader表上分別創(chuàng)建BEFOREINSERT和AFTERINSERT觸發(fā)器,當(dāng)向T_reader表中插入記錄時(shí),通過(guò)兩個(gè)觸發(fā)器向T_borrow表中分別插入一行記錄,觀察這兩個(gè)觸發(fā)器的觸發(fā)順序。1)創(chuàng)建T_reader表,SQL語(yǔ)句如下:USEstudentinfo;DROPTABLEIFEXISTST_reader;CREATETABLET_reader(ReaderIDCHAR(6),ReaderNameVARCHAR(10));10.1觸發(fā)器2)創(chuàng)建T_borrow表,SQL語(yǔ)句如下:DROPTABLEIFEXISTST_borrow;CREATETABLET_borrow(ReaderIDCHAR(6),BookIDCHAR(10),TriggerTimeTIMESTAMPNOTNULLDEFAULTNOW());10.1觸發(fā)器3)創(chuàng)建T_reader表上的觸發(fā)器tr_before_insert,SQL語(yǔ)句如下:DROPTRIGGERIFEXISTStr_before_insert;CREATETRIGGERtr_before_insertBEFOREINSERTONT_readerFOREACHROWBEGININSERTINTOT_borrowSETReaderID='111111',BookID='AAAAAAAAAA';END;10.1觸發(fā)器4)創(chuàng)建T_reader表上的tr_after_insert觸發(fā)器,SQL語(yǔ)句如下:DROPTRIGGERIFEXISTStr_after_insert;CREATETRIGGERtr_after_insertAFTERINSERTONT_readerFOREACHROWBEGININSERTINTOT_borrowSETReaderID='222222',BookID='BBBBBBBBBB';END;10.1觸發(fā)器6)測(cè)試觸發(fā)器,向T_reader表中插入一條記錄,SQL語(yǔ)句如下:INSERTINTOT_reader(ReaderID,ReaderName)VALUES('666666','孟琳');7)查看T_borrow表中插入記錄的順序和時(shí)間,SQL語(yǔ)句和運(yùn)行結(jié)果如下:SELECT*FROMT_borrow;10.1觸發(fā)器4.觸發(fā)器發(fā)生錯(cuò)誤時(shí)的處理方式10.1觸發(fā)器10.3.7觸發(fā)器的使用實(shí)例BEFOREINSERT觸發(fā)器使用方法【例10-7】創(chuàng)建觸發(fā)器tr_student_insert,在向student表插入學(xué)生記錄前先檢查待插入學(xué)生記錄的學(xué)號(hào),如果該學(xué)號(hào)在student表中不存在則插入,否則返回錯(cuò)誤信息。1)創(chuàng)建觸發(fā)器。DROPTRIGGERIFEXISTStr_student_insert;CREATETRIGGERtr_student_insertBEFOREINSERTONstudentFOREACHROWBEGINDECLAREmessage_textCHAR(10)DEFAULT"";DECLAREidCHAR(12)DEFAULTNULL;SETid=(SELECTStudentIDFROMstudentWHEREStudentID=NEW.StudentID);IF(idISNOTNULL)THENSIGNALSQLSTATE'45000'SETmessage_text='該學(xué)號(hào)已存在';#返回錯(cuò)誤信息ENDIF;END;10.1觸發(fā)器2)測(cè)試觸發(fā)器。SELECT*FROMstudentWHEREStudentID='202263050133';

INSERTINTOstudent(StudentID,StudentName,Sex,Birthday,Address,ClassID)VALUES('202263050133','陳一杰','男','2003-06-01','浙江','2022630501');

SELECT*FROMstudentWHEREStudentID='202263050133';10.1觸發(fā)器③INSERTINTOstudent(StudentID,StudentName,Sex,Birthday,Address,ClassID)VALUES('202263050188','陳一杰','男','2003-06-01','浙江','2022630501');

SELECT*FROMstudentWHEREStudentID='202263050188';10.1觸發(fā)器2.AFTERINSERT觸發(fā)器使用方法【例10-8】在student表中插入新學(xué)生記錄后,將插入記錄成功的信息寫(xiě)入到student_status表中。1)創(chuàng)建一個(gè)student_status表,用于保存student表中學(xué)生的備注信息。DROPTABLEIFEXISTSstudent_status;CREATETABLEstudent_status(StudentIDCHAR(12)PRIMARYKEY,StatusNotesVARCHAR(10))ENGINE=INNODB;10.1觸發(fā)器2)創(chuàng)建觸發(fā)器。DROPTRIGGERIFEXISTStr_student_status_insert;CREATETRIGGERtr_student_status_insertAFTERINSERTONstudentFOREACHROWBEGININSERTINTOstudent_status(StudentID,StatusNotes)VALUES(NEW.StudentID,'學(xué)生記錄插入成功');END;10.1觸發(fā)器2)測(cè)試觸發(fā)器。①I(mǎi)NSERTINTOstudent(StudentID,StudentName,Sex,Birthday,Address,ClassID)VALUES('202263050199','高琳','女','2003-07-01','天津','20226305');②SELECT*FROMstudent_status;10.1觸發(fā)器3.BEFOREUPDATE觸發(fā)器使用方法【例10-9】在selectcourse表上創(chuàng)建一個(gè)用于檢查修改成績(jī)的觸發(fā)器tr_selectcourse_cheek,使得成績(jī)位于0~100的范圍內(nèi),如果分?jǐn)?shù)大于100則為100;如果分?jǐn)?shù)小于0則為0。1)CREATETRIGGERttr_selectcourse_cheekBEFOREUPDATEONselectcourseFOREACHROWBEGINIFNEW.Score<0THENSETNEW.Score=0;ELSEIFNEW.Score>100THENSETNEW.Score=100;ENDIF;END;10.1觸發(fā)器2)測(cè)試觸發(fā)器。①SELECT*FROMselectcourseWHEREStudentID='202263050133';

②UPDATEselectcourseSETScore=120WHEREStudentID='202263050133'ANDCourseID='630575';UPDATEselectcourseSETScore=-10WHEREStudentID='202263050133'ANDCourseID='630572';10.1觸發(fā)器②UPDATEselectcourseSETScore=120WHEREStudentID='202263050133'ANDCourseID='630575';UPDATEselectcourseSETScore=-10WHEREStudentID='202263050133'ANDCourseID='630572';③SELECT*FROMselectcourseWHEREStudentID='202263050133';10.1觸發(fā)器4.AFTERUPDATE觸發(fā)器使用方法【例10-10】創(chuàng)建一個(gè)觸發(fā)器tri_update_courseid,當(dāng)修改課程表course中某門(mén)課的課程號(hào)時(shí),同時(shí)修改成績(jī)表selectcourse中的相同的全部課程號(hào)。1)創(chuàng)建觸發(fā)器。CREATETRIGGERtri_update_courseidAFTERUPDATEONcourseFOREACHROWBEGINUPDATEselectcourseSETCourseID=NEW.CourseIDWHERECourseID=OLD.CourseID;END;10.1觸發(fā)器2)ALTERTABLEselectcourseDROPFOREIGNKEYFK_selectcourse_course;3)測(cè)試觸發(fā)器。①SELECT*fromcourseWHERECourseID='100101';

SELECT*fromselectcourseWHERECourseID='100101';10.1觸發(fā)器②UPDATEcourseSETCourseID='100111'WHERECourseID='100101';

SELECT*fromcourseWHERECourseID='100111';

SELECT*fromselectcourseWHERECourseID='100111';

10.1觸發(fā)器【例10-11】在selectcourse表上創(chuàng)建一個(gè)觸發(fā)器,當(dāng)在成績(jī)表selectcourse中修改了某一學(xué)生的某一課程的成績(jī)后,則把修改時(shí)間、學(xué)號(hào)、課程編號(hào)、修改前成績(jī)、修改后成績(jī)保存到log_trigger日志表中。1)CREATETABLElog_trigger(ExecTimeDATETIME,StudentIDCHAR(12),CourseIDCHAR(6),ScoreOldDECIMAL(4,1),ScoreNewDECIMAL(4,1));10.1觸發(fā)器2)CREATETRIGGERtr_selectcourse_updateAFTERUPDATEONselectcourseFOREACHROWBEGININSERTINTOlog_trigger(ExecTime,StudentID,CourseID,ScoreOld,ScoreNew)VALUES(NOW(),NEW.StudentID,NEW.CourseID,OLD.Score,NEW.Score);END;10.1觸發(fā)器2)測(cè)試觸發(fā)器。SELECT*FROMselectcourseWHEREStudentID='202263050132'ANDCourseID='630572';

UPDATEselectcourseSETScore=99WHEREStudentID='202263050132'ANDCourseID='630572';10.1觸發(fā)器SELECT*FROMselectcourseWHEREStudentID='202263050132'ANDCourseID='630572';

SELECT*FROMlog_trigger;10.1觸發(fā)器5.BEFOREDELETE觸發(fā)器使用方法【例10-12】在student表上,創(chuàng)建一個(gè)觸發(fā)器,在student表中刪除一行記錄之前,先在selectcourse表中刪除該學(xué)生的成績(jī)記錄。1)創(chuàng)建觸發(fā)器。DROPTRIGGERIFEXISTStr_student_delete_score;CREATETRIGGERtr_student_delete_scoreBEFOREDELETEONstudentFOREACHROWBEGIN#先在成績(jī)表selectcourse中刪除該學(xué)生的成績(jī)記錄

DELETEFROMselectcourseWHEREStudentID=(SELECTStudentIDFROMstudentWHEREStudentID=OLD.StudentID);END;10.1觸發(fā)器2)測(cè)試觸發(fā)器。①SELECT*FROMstudentWHEREStudentID='202263050133';

SELECT*FROMselectcourseWHEREStudentID='202263050133';10.1觸發(fā)器②DELETEFROMstudentWHEREStudentID='202263050133';

③SELECT*FROMstudentWHEREStudentID='202263050133';

SELECT*FROMselectcourseWHEREStudentID='202263050133';

10.1觸發(fā)器6.AFTERDELETE觸發(fā)器使用方法【例10-13】在例10-12的基礎(chǔ)上,在表student中再創(chuàng)建一個(gè)觸發(fā)器,每次在student表中刪除學(xué)生記錄后,都把被刪除記錄的學(xué)號(hào)列StudentID的值賦值給用戶(hù)變量@old_stuID,@count記錄刪除記錄的個(gè)數(shù)。1)創(chuàng)建觸發(fā)器。SET@old_StuID="",@count=0;#記錄被刪除學(xué)生的學(xué)號(hào)和個(gè)數(shù)DROPTRIGGERIFEXISTStr_student_delete;CREATETRIGGERtr_student_deleteAFTERDELETEONstudentFOREACHROWBEGINSET@old_StuID=CONCAT_WS(',',@old_StuID,OLD.StudentID);SET@count=@count+1;END;10.1觸發(fā)器2)測(cè)試觸發(fā)器。①SELECT*FROMstudentWHEREStudentID='202263050135';

SELECT*FROMselectcourseWHEREStudentID='202263050135';

10.1觸發(fā)器②DELETEFROMstudentWHEREStudentID='202263050135';

③SELECT@old_StuID,@count;

10.1觸發(fā)器④SELECT*FROMstudentWHEREStudentID='202260010306';SELECT*FROMselectcourseWHEREStudentID='202260010306';DELETEFROMstudentWHEREStudentID='202260010306';SELECT@old_StuID,@count;10.1觸發(fā)器【例10-14】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建回收站觸發(fā)器,當(dāng)刪除員工表employee中的記錄時(shí),把刪除的記錄保存到回收站表trash中。1)①創(chuàng)建員工表,SQL語(yǔ)句如下:CREATETABLEemployee(idBIGINT(20)NOTNULLAUTO_INCREMENT,nameVARCHAR(20)DEFAULTNULL,ageINT(11)DEFAULTNULL,PRIMARYKEY(id))ENGINE=InnoDBDEFAULTCHARSET=utf8;10.1觸發(fā)器②INSERTINTOemployee(name,age)VALUES('張三',19),('李四',18),('王五',20),('趙六',21),('陳七',19),('錢(qián)八',20);10.1觸發(fā)器③CREATETABLEtrash(idBIGINT(20)NOTNULLAUTO_INCREMENT,dataVARCHAR(255)DEFAULTNULL,PRIMARYKEY(id))ENGINE=InnoDBDEFAULTCHARSET=utf8;10.1觸發(fā)器2)--DROPTRIGGERIFEXISTStrigger_del_employee;CREATETRIGGERtrigger_del_employeeAFTERDELETEONemployeeFOREACHROWINSERTINTOtrash(data)VALUES(CONCAT('employee刪除:',OLD.id,'|',OLD.name,'|',OLD.age));10.1觸發(fā)器3)測(cè)試觸發(fā)器。①DELETEFROMemployeeWHEREid=3;②SELECT*FROMtrash;10.1觸發(fā)器10.2.1事件的概念1.查看事件調(diào)度器SHOWVARIABLESLIKE'event_scheduler';SELECT@@event_scheduler;10.2事件2.開(kāi)啟事件調(diào)度器SETGLOBALevent_scheduler=ON;打開(kāi)事件調(diào)度器SET@@GLOBAL.event_scheduler=ON;在my.ini中開(kāi)啟事件:SETGLOBALevent_scheduler=ON10.2事件10.2.2創(chuàng)建事件CREATEEVENT[IFNOTEXISTS]event_nameONSCHEDULEschedule[ONCOMPLETION[NOT]PRESERVE][{ENABLE|DISABLE|DISABLEONSLAVE}][COMMENT'comment']DOevent_body;10.2事件①AT子句。ATtimestamp[+INTERVALinterval]...quantity{YEAR|QUARTER|MONTH|DAY|HOUR|MINUTE|WEEK|SECOND|YEAR_MONTH|DAY_HOUR|DAY_MINUTE|DAY_SECOND|HOUR_MINUTE|HOUR_SECOND|MINUTE_SECOND}10.2事件EVERYinterval[STARTStimestamp[+INTERVALinterval]...][ENDStimestamp[+INTERVALinterval]...]10.2事件10.2.3事件的使用實(shí)例1.創(chuàng)建某個(gè)時(shí)刻發(fā)生的事件【例10-15】在studentinfo數(shù)據(jù)庫(kù)中,創(chuàng)建一個(gè)現(xiàn)在立即執(zhí)行的事件ev_create_user,事件執(zhí)行創(chuàng)建一個(gè)表t_user。1)創(chuàng)建事件。USEstudentinfo;DROPEVENTIFEXISTSev_create_user;CREATEEVENTev_create_userONSCHEDULEATNOW()DOBEGINDROPTABLEIFEXISTSt_user;

CREATETABLEt_user(T_IdINTPRIMARYKEYAUTO_INCREMENTCOMMENT'用戶(hù)編號(hào)',T_NameCHAR(10)COMMENT'用戶(hù)名',T_CreateTimeTIMESTAMPCOMMENT'創(chuàng)建時(shí)間')COMMENT='用戶(hù)表';END;10.2事件2)查看事件結(jié)果。SELECT*FROMt_user;10.2事件【例10-16】創(chuàng)建一個(gè)事件ev_insert_user30,30秒后啟動(dòng)事件,向t_user表中插入一行記錄。1)CREATEEVENTev_insert_user30ONSCHEDULEATCURRENT_TIMESTAMP+INTERVAL30SECONDDOINSERTINTOt_user(T_Name,T_CreateTime)VALUES('AAA',NOW());2)SELECT*FROMt_user;10.2事件SELECT*FROMt_user;

SHOWEVENTS;10.2事件2.創(chuàng)建在指定區(qū)間周期性發(fā)生的事件(1)常用的時(shí)間間隔1)ONSCHEDULEEVERY5SECOND2)ONSCHEDULEEVERY1MINUTE10.2事件3)ONSCHEDULEEVERY1DAYSTARTSDATE_ADD(DATE_ADD(CURDATE(),INTERVAL1DAY),INTERVAL1HOUR)4)ONSCHEDULEEVERY1MONTHSTARTSDATE_ADD(DATE_ADD(DATE_SUB(CURDATE(),INTE

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論