數(shù)據(jù)庫系統(tǒng)原理與設(shè)計(jì)實(shí)驗(yàn)教程 第4版 課件 第5-7章 數(shù)據(jù)庫編程技術(shù)、數(shù)據(jù)庫事務(wù)處理、數(shù)據(jù)庫設(shè)計(jì)_第1頁
數(shù)據(jù)庫系統(tǒng)原理與設(shè)計(jì)實(shí)驗(yàn)教程 第4版 課件 第5-7章 數(shù)據(jù)庫編程技術(shù)、數(shù)據(jù)庫事務(wù)處理、數(shù)據(jù)庫設(shè)計(jì)_第2頁
數(shù)據(jù)庫系統(tǒng)原理與設(shè)計(jì)實(shí)驗(yàn)教程 第4版 課件 第5-7章 數(shù)據(jù)庫編程技術(shù)、數(shù)據(jù)庫事務(wù)處理、數(shù)據(jù)庫設(shè)計(jì)_第3頁
數(shù)據(jù)庫系統(tǒng)原理與設(shè)計(jì)實(shí)驗(yàn)教程 第4版 課件 第5-7章 數(shù)據(jù)庫編程技術(shù)、數(shù)據(jù)庫事務(wù)處理、數(shù)據(jù)庫設(shè)計(jì)_第4頁
數(shù)據(jù)庫系統(tǒng)原理與設(shè)計(jì)實(shí)驗(yàn)教程 第4版 課件 第5-7章 數(shù)據(jù)庫編程技術(shù)、數(shù)據(jù)庫事務(wù)處理、數(shù)據(jù)庫設(shè)計(jì)_第5頁
已閱讀5頁,還剩71頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第1頁第5章數(shù)據(jù)庫編程技術(shù)數(shù)據(jù)庫系統(tǒng)原理實(shí)驗(yàn)教程第4版5.1相關(guān)知識(shí)5.1.1游標(biāo)5.1.2存儲(chǔ)過程5.1.3觸發(fā)器5.2實(shí)驗(yàn)十二游標(biāo)與存儲(chǔ)過程5.2.1實(shí)驗(yàn)?zāi)康呐c要求5.2.2實(shí)驗(yàn)案例5.2.3實(shí)驗(yàn)內(nèi)容5.3實(shí)驗(yàn)十三觸發(fā)器5.3.1實(shí)驗(yàn)?zāi)康呐c要求5.3.2實(shí)驗(yàn)案例5.3.3實(shí)驗(yàn)內(nèi)容目錄第3頁5.1相關(guān)知識(shí)5.1.1游標(biāo)游標(biāo)是一種允許用戶訪問單獨(dú)的數(shù)據(jù)行的數(shù)據(jù)訪問機(jī)制。游標(biāo)主要用在存儲(chǔ)過程、觸發(fā)器和T-SQL腳本中,使用游標(biāo),可以對(duì)由SELECT語句返回的結(jié)果集記錄進(jìn)行逐行處理。使用游標(biāo)必須經(jīng)歷五個(gè)步驟:①定義游標(biāo):DECLARE②打開游標(biāo):OPEN③逐行提取游標(biāo)集中的行:FETCH④關(guān)閉游標(biāo):CLOSE⑤釋放游標(biāo):DEALLOCATE第4頁1.定義游標(biāo)語法:DECLAREcursor_nameSCROLLCURSORFORsql_staments[FOR[READONLY|UPDATE{OFcolumn_name_list[,...n]]]其中:·cursor_name:用戶定義的游標(biāo)名?!ql_staments:定義游標(biāo)結(jié)果集的標(biāo)準(zhǔn)SELECT語句。·FOR:后面的短語定義游標(biāo)屬性只讀或更新,缺省時(shí)為UPDATE?!PDATE{OFcolumn_name_list}:定義游標(biāo)內(nèi)可更新的列。如果指定OFcolumn_name_list[,...n]參數(shù),則只允許修改所列出的列。如果在UPDATE中未指定列的列表,則可以更新所有列。第5頁·READONLY:在UPDATE或DELETE語句的WHERECURRENTOF子句中不能引用游標(biāo)。該選項(xiàng)替代要更新的游標(biāo)的默認(rèn)功能?!CROLL:指定所有的提取選項(xiàng)(FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE)均可用。如果在DECLARECURSOR中未指定SCROLL,則NEXT是唯一支持的提取選項(xiàng)。注意:①當(dāng)游標(biāo)移至尾部,不可以再讀取游標(biāo),必須關(guān)閉游標(biāo)然后重新打開游標(biāo)。②可以通過檢查全局變量@@fetch_status來判斷是否已讀完游標(biāo)集中所有行。第6頁2.打開游標(biāo)使用OPEN語句執(zhí)行SELECT語句并生成游標(biāo)。語法為:OPENcurser_name3.提取游標(biāo)①逐行提取游標(biāo)集中的行:FETCHcurser_name[INTO@variable_name[,...n]]②FETCH[[NEXT|PRIOR|FIRST|LAST|ABSOLUTE{n|@nvar

}|Relative{n|@nvar}][FROM{cursor_name|@cursor_variable_name}[INTO@variable_name[,...n]]第7頁其中:·NEXT:返回緊跟當(dāng)前行之后的結(jié)果行,并且當(dāng)前行遞增為結(jié)果行。如果FETCHNEXT為對(duì)游標(biāo)的第一次提取操作,則返回結(jié)果集中的第一行。NEXT為默認(rèn)的游標(biāo)提取選項(xiàng)?!RIOR:返回緊臨當(dāng)前行前面的結(jié)果行,并且當(dāng)前行遞減為結(jié)果行。如果FETCHPRIOR為對(duì)游標(biāo)的第一次提取操作,則沒有行返回并且游標(biāo)置于第一行之前?!IRST:返回游標(biāo)中的第一行并將其作為當(dāng)前行?!AST:返回游標(biāo)中的最后一行并將其作為當(dāng)前行?!BSOLUTE{n|@nvar}:如果n或@nvar為正數(shù),返回從游標(biāo)頭開始的第n行并將返回的行變成新的當(dāng)前行。如果n或@nvar為負(fù)數(shù),返回游標(biāo)尾之前的第n行并將返回的行變成新的當(dāng)前行。如果n或@nvar為0,則沒有行返回。n必須為整型常量且@nvar必須為smallint、tinyint或int?!ELATIVE{n|@nvar}:如果n或@nvar為正數(shù),返回當(dāng)前行之后的第n行并將返回的行變成新的當(dāng)前行。如果n或@nvar為負(fù)數(shù),返回當(dāng)前行之前的第n行并將返回的行變成新的當(dāng)前行。如果n或@nvar為0,返回當(dāng)前行。如果對(duì)游標(biāo)的第一次提取操作時(shí)將FETCHRELATIVE的n或@nvar指定為負(fù)數(shù)或0,則沒有行返回。n必須為整型常量且@nvar必須為smallint、tinyint或int。·INTO@variable_name[,...n]:把每列中的數(shù)據(jù)轉(zhuǎn)移到指定的變量中。

第8頁4.關(guān)閉游標(biāo)關(guān)閉游標(biāo)可以釋放某些資源,如游標(biāo)結(jié)果集和對(duì)當(dāng)前行的鎖定,如果重新發(fā)出一個(gè)OPEN語句,則該游標(biāo)結(jié)構(gòu)仍可用于處理。語法為:CLOSEcurser_name5.釋放游標(biāo)DEALLOCATE語句則完全釋放分配給游標(biāo)的資源,包括游標(biāo)名稱。在游標(biāo)被釋放后,必須使用DECLARE語句重新生成游標(biāo)。語法為:DEALLOCATEcurser_name6.刪除游標(biāo)集中當(dāng)前行語法:DELETEFROMtable_nameWHERECURRENTOFcurser_name注意:從游標(biāo)中刪除一行后,游標(biāo)定位于被刪除的游標(biāo)之后的一行,必須再用FETCH得到該行。第9頁7.更新游標(biāo)集中當(dāng)前行語法:UPDATEtable_name

SETcolumn_name=expression[,column_name=expression]WHERECURRENTOFcurser_name第10頁5.1.2存儲(chǔ)過程SQLServer提供了一種方法,它可以將一些固定的操作集中起來由SQLServer數(shù)據(jù)庫服務(wù)器來完成,以實(shí)現(xiàn)某個(gè)任務(wù),這種方法就是存儲(chǔ)過程。存儲(chǔ)過程是經(jīng)過編譯和優(yōu)化后存儲(chǔ)在數(shù)據(jù)庫服務(wù)器中SQL語句寫的過程,使用時(shí)只要調(diào)用即可。存儲(chǔ)過程的優(yōu)點(diǎn)是:(1)提供了在服務(wù)器端快速執(zhí)行SQL語句的有效途徑。(2)降低了客戶機(jī)和服務(wù)器之間的通信量(3)方便實(shí)施企業(yè)規(guī)則。(4)業(yè)務(wù)封裝后,對(duì)數(shù)據(jù)庫系統(tǒng)提供了一定的安全保證。第11頁創(chuàng)建存儲(chǔ)過程時(shí),需要確定存儲(chǔ)過程的3個(gè)組成部分:①所有的輸入?yún)?shù)以及傳給調(diào)用者的輸出參數(shù)。②被執(zhí)行的針對(duì)數(shù)據(jù)庫的操作語句,包括調(diào)用其它存儲(chǔ)過程的語句。③返回給調(diào)用者的狀態(tài)值,以指明調(diào)用是成功還是失敗。第12頁1.創(chuàng)建存儲(chǔ)過程語法:CREATEPROCEDUREprocedure_name

[;number][{@parameterdatatype}[OUTPUT]][,...n]ASsql_statement[,...n]其中:·procedure_name:存儲(chǔ)過程的名稱。創(chuàng)建臨時(shí)過程,在procedure_name前面加一個(gè)編號(hào)符,即#procedure_name;創(chuàng)建全局臨時(shí)過程,在procedure_name前面加兩個(gè)編號(hào)符,即##procedure_name。完整的名稱(包括#或##)不能超過128個(gè)字符。過程所有者的名稱是可選的。第13頁·number:是可選的整數(shù),用來對(duì)同名的過程分組,以便用一條DROPPROCEDURE語句即可將同組的過程一起除去。例如,名為orders的應(yīng)用程序使用的過程可以命名為orderproc;1、orderproc;2等。DROPPROCEDUREorderproc語句將除去整個(gè)組。·@parameter:過程中的參數(shù),最多可以有2100個(gè)參數(shù)。·datatype:參數(shù)的數(shù)據(jù)類型。所有數(shù)據(jù)類型(包括text、ntext和image)均可以用作存儲(chǔ)過程的參數(shù)?!UTPUT:表明參數(shù)是輸出參數(shù),text、ntext和image參數(shù)可用作OUTPUT參數(shù)。使用OUTPUT關(guān)鍵字的輸出參數(shù)可以是游標(biāo)占位符?!:表示最多可以指定2100個(gè)參數(shù)的占位符?!S:指定過程要執(zhí)行的操作。·sql_statement:過程中的Transact-SQL語句。第14頁2.執(zhí)行存儲(chǔ)過程語法:EXECUTE{procedure_name[;number]|@procedure_name_var}[OUTPUT][,...n]其中:·procedure_name:擬調(diào)用的存儲(chǔ)過程名?!procedure_name_var:局部定義的變量名?!parameter:過程參數(shù),在CREATEPROCEDURE語句中定義。參數(shù)名稱前必須加上符號(hào)@。在以@parameter_name=value格式使用時(shí),參數(shù)名稱和常量不一定按照CREATEPROCEDURE語句中定義的順序出現(xiàn)。但是,如果有一個(gè)參數(shù)使用@parameter_name=value格式,則其它所有參數(shù)都必須使用這種格式?!UTPUT:指定存儲(chǔ)過程必須返回一個(gè)參數(shù)。使用OUTPUT參數(shù),參數(shù)值必須作為變量傳遞。在執(zhí)行過程之前,必須聲明變量的數(shù)據(jù)類型并賦值。返回參數(shù)可以是text或image數(shù)據(jù)類型以外的任意數(shù)據(jù)類型。第15頁3.重命名存儲(chǔ)過程語法:

Sp_rename'procedure_name1','procedure_name2'4.刪除存儲(chǔ)過程語法:

DROPPROCEDUREprocedure_name第16頁5.1.3觸發(fā)器觸發(fā)器是一種特殊的存儲(chǔ)過程,當(dāng)INSERT、DELETE或UPDATE語句修改指定表的一行或多行時(shí),自動(dòng)執(zhí)行觸發(fā)器。在觸發(fā)器的使用中,系統(tǒng)會(huì)自動(dòng)產(chǎn)生兩張臨時(shí)表Deleted和Inserted。用戶不能直接修改這兩個(gè)表的內(nèi)容。①Deleted表:存儲(chǔ)在DELETE和UPDATE語句執(zhí)行時(shí)所影響的行的拷貝,在DELETE和UPDATE語句執(zhí)行前被作用的行轉(zhuǎn)移到Deleted表中。②Inserted表:存儲(chǔ)在INSTERT和UPDATE語句執(zhí)行時(shí)所影響的行的拷貝,在Insert和UPDATE語句執(zhí)行期間,新行被同時(shí)加到Inserted和觸發(fā)器表中。第17頁觸發(fā)器僅在當(dāng)前DB中生成,觸發(fā)器有3種類型,即插入、刪除和更新。(1)INSERT類型的觸發(fā)器:當(dāng)對(duì)指定表TableName執(zhí)行了插入操作時(shí)系統(tǒng)自動(dòng)執(zhí)行觸發(fā)器代碼。(2)UPDATE類型的觸發(fā)器:當(dāng)對(duì)指定表TableName執(zhí)行了更新操作時(shí)系統(tǒng)自動(dòng)執(zhí)行觸發(fā)器代碼。(3)DELETE類型的觸發(fā)器:當(dāng)對(duì)指定表TableName執(zhí)行了刪除操作時(shí)系統(tǒng)自動(dòng)執(zhí)行觸發(fā)器代碼。第18頁在觸發(fā)器內(nèi)不能使用如下的SQL命令:①所有數(shù)據(jù)庫對(duì)象的生成命令,如CREATETABLE、CREATEINDEX等。②所有數(shù)據(jù)庫對(duì)象的結(jié)構(gòu)修改命令,如ALTERTABLE、ALTERDATABASE等。③創(chuàng)建臨時(shí)保存表。④所有DROP命令。⑤GRANT和REVOKE命令。⑥TRUNCATETABLE命令。⑦LOADDATABASE和LOADTRANSACTION命令。

⑧RECONFIGURE命令。第19頁1.創(chuàng)建觸發(fā)器語法:CREATETRIGGERtrigger_nameONtable_nameFOR<INSERT|UPDATE|DELETE>AS

sql_statement2.刪除觸發(fā)器語法:DROPTRIGGERtrigger_name3.修改觸發(fā)器語法:ALTERTRIGGERtriggernameONtable_nameFOR<INSERT|UPDATE|DELETE>ASsql_statement第20頁5.2實(shí)驗(yàn)十二游標(biāo)與存儲(chǔ)過程5.2.1實(shí)驗(yàn)?zāi)康呐c要求(1)掌握游標(biāo)的定義和使用方法。(2)掌握存儲(chǔ)過程的定義、執(zhí)行和調(diào)用方法。(3)掌握游標(biāo)和存儲(chǔ)過程的綜合應(yīng)用方法。第21頁5.2.2實(shí)驗(yàn)案例[例5.1]利用游標(biāo)查詢業(yè)務(wù)科員工的編號(hào)、姓名、性別、部門和薪水,并逐行顯示游標(biāo)中的信息。DECLAREcur_empSCROLLCURSORFORSELECTemployeeno,employeename,sex,department,salaryFROMemployeeWHEREdepartment='業(yè)務(wù)科'ORDERBYemployeeno/*定義游標(biāo)*/OPENcur_emp

/*打開游標(biāo)*/SELECT'CURSOR內(nèi)數(shù)據(jù)條數(shù)'=@@cursor_rows

/*顯示游標(biāo)內(nèi)記錄的個(gè)數(shù)*/FETCHNEXTFROMcur_emp

/*逐行提取游標(biāo)中的記錄*/WHILE(@@FETCH_status<>-1)/*判斷FETCH語句是否執(zhí)行成功*/BEGINSELECT'cursor讀取狀態(tài)'=@@FETCH_status/*顯示游標(biāo)的讀取狀態(tài)*/FETCHNEXTFROMcur_emp/*提取游標(biāo)下一行信息*/ENDCLOSEcur_emp

/*關(guān)閉游標(biāo)*/DEALLOCATEcur_emp

/*釋放游標(biāo)*/第22頁

本例中,@@cursor_rows是返回連接上最后打開的游標(biāo)中當(dāng)前存在的合格行的數(shù)量。具體參數(shù)信息見表5-1所示。第23頁@@FETCH_status是返回被FETCH語句執(zhí)行的最后,而不是任何當(dāng)前被連接打開的游標(biāo)的狀態(tài)。具體參數(shù)見表5-2所示。第24頁[例5.2]利用游標(biāo)查詢業(yè)務(wù)科員工的編號(hào)、姓名、性別、部門和薪水,并以格式化的方式輸出游標(biāo)中的信息。DECLARE@emp_nochar(8),@emp_namechar(10),@sexchar(1),@deptchar(4)DECLARE@salarynumeric(8,2),@textchar(100)/*用戶自定義的幾個(gè)變量*/DECLAREemp_curSCROLLCURSORFORSELECTemployeeNo,employeeName,sex,department,salaryFROMEmployeeWHEREdepartment='業(yè)務(wù)科'ORDERBYemployeeNo/*定義游標(biāo)*/SELECT@text='========業(yè)務(wù)科員工情況列表==========='PRINT@textSELECT@text='編號(hào)

姓名

性別

部門

薪水'PRINT@textSELECT@text='----------------------------------'PRINT@text/*按照用戶要求格式化輸出相關(guān)信息*/OPENemp_cur

/*打開游標(biāo)*/第25頁FETCHemp_curINTO@emp_no,@emp_name,@sex,@dept,@salary/*提取游標(biāo)中的信息傳遞并分別給內(nèi)存變量*/WHILE(@@FETCH_status=0)/*判斷是否提取成功*/BEGINSELECT@text=@emp_no+''+@emp_name+''+@sex+''+@dept+''+convert(char(10),@salary)/*給@text賦字符串值*/PRINT@text/*打印字符串值*//*提取游標(biāo)中的信息傳遞并分別給內(nèi)存變量*/FETCHemp_curinto@emp_no,@emp_name,@sex,@dept,@salaryENDCLOSEemp_cur

/*關(guān)閉游標(biāo)*/DEALLOCATEemp_cur

/*釋放游標(biāo)*/本例中,主要結(jié)合SELECT和PRINT命令將創(chuàng)建游標(biāo)后逐行提取游標(biāo)的信息以格式化的方式輸出,提高了腳本的可讀性

第26頁[例5.3]不帶參數(shù)的存儲(chǔ)過程:利用存儲(chǔ)過程計(jì)算出’E2020002’業(yè)務(wù)員的銷售總金額。①創(chuàng)建存儲(chǔ)過程CREATEPROCEDUREsales_tot1ASSELECTsum(orderSum)FROMOrderMasterWHEREsalerNo=’E2020002’②執(zhí)行存儲(chǔ)過程EXECsales_tot1上述操作只能統(tǒng)計(jì)業(yè)務(wù)員’E2020002’的銷售業(yè)績(jī),執(zhí)行此存儲(chǔ)過程不能統(tǒng)計(jì)任意一個(gè)業(yè)務(wù)員的銷售業(yè)績(jī)。第27頁[例5.4]帶輸入?yún)?shù)的存儲(chǔ)過程:統(tǒng)計(jì)某業(yè)務(wù)員的銷售總金額。①創(chuàng)建存儲(chǔ)過程CREATEPROCEDUREsales_tot2@e_no

char(8)ASSELECTsum(orderSum)FROMOrderMasterWHEREsalerNo=@e_no②執(zhí)行存儲(chǔ)過程EXECsales_tot2'E2020003'

注:

程序中使用@符號(hào)表示一個(gè)變量來指定參數(shù)名稱,且每個(gè)過程的參數(shù)僅用于該過程本身。上述操作只要在執(zhí)行存儲(chǔ)過程時(shí)添加輸入?yún)?shù)(即被統(tǒng)計(jì)的業(yè)務(wù)員的編號(hào))就能統(tǒng)計(jì)任一業(yè)務(wù)員的銷售業(yè)績(jī)。問題:任意一個(gè)業(yè)務(wù)員的銷售總金額如何被其他用戶/程序方便調(diào)用呢?

第28頁[例5.5]帶輸入/輸出參數(shù)的存儲(chǔ)過程:統(tǒng)計(jì)某業(yè)務(wù)員的銷售總金額并返回其結(jié)果。①創(chuàng)建存儲(chǔ)過程CREATEPROCEDUREsales_tot3@E_nochar(8),@p_tot

intOUTPUTASSELECT@p_tot=sum(orderSum)FROMOrderMasterWHEREsalerNo=@E_no②執(zhí)行存儲(chǔ)過程DECLARE@tot_amt

intEXECsales_tot3'E2020003',@tot_amtOUTPUTSELECT銷售總額=@tot_amt上述操作可以統(tǒng)計(jì)任一員工的銷售業(yè)績(jī)并能實(shí)現(xiàn)其結(jié)果的調(diào)用。第29頁[例5.6]帶通配符參數(shù)的存儲(chǔ)過程(模糊查找):統(tǒng)計(jì)所有姓陳的員工的銷售業(yè)績(jī)并輸出他們姓名和所在部門。①創(chuàng)建存儲(chǔ)過程CreateProcedureemp_name

@E_name

varchar(10)ASSELECTa.EmployeeName,a.department,ssumFROMEmployeea,(SELECTSalerNo,ssum=sum(OrderSum)FROMOrderMasterGROUPBYSalerNo)bWHEREa.EmployeeNo=b.SalerNoANDa.EmployeeNameLIKE@E_name②執(zhí)行存儲(chǔ)過程EXECemp_name

@E_name='陳%'第30頁[例5.7]重命名存儲(chǔ)過程:將存儲(chǔ)過程sales_tot2改名為sale_tot。

Sp_rename‘sales_tot2’,‘sale_tot’[例5.8]刪除存儲(chǔ)過程:將存儲(chǔ)過程sale_tot刪除。DROPPROCEDUREsale_tot第31頁[例5.9]游標(biāo)和存儲(chǔ)過程的綜合應(yīng)用:請(qǐng)使用游標(biāo)和循環(huán)語句編寫一個(gè)存儲(chǔ)過程emp_tot,根據(jù)業(yè)務(wù)員姓名,查詢?cè)摌I(yè)務(wù)員在銷售工作中的客戶信息及每一客戶的銷售記錄,并輸出該業(yè)務(wù)員的銷售總金額。第32頁①創(chuàng)建存儲(chǔ)過程CREATEPROCEDUREemp_tot@v_emp_namechar(10)ASBEGINDECLARE@sv_emp_namevarchar(10),@v_custnamevarchar(10),@p_totintDECLARE@sumint,@countint,@order_novarchar(10)SELECT@sum=0,@count=0DECLAREget_totCURSORFORSELECTEmployeeName,CustomerNo,b.OrderNo,OrderSumFROMEmployeea,OrderMasterbWHEREa.EmployeeName=@v_emp_nameANDa.EmployeeNo=b.SalerNoOPENget_totFETCHget_totINTO@sv_emp_name,@v_custname,@order_no,@p_tot第33頁WHILE(@@FETCH_status=0)

BEGIN

SELECT業(yè)務(wù)員=@sv_emp_name,客戶=@v_custname,訂單編號(hào)=@order_no,訂單金額=@p_totSELECT@sum=@sum+@p_totSELECT@count=@count+1FETCHget_totINTO@sv_emp_name,@v_custname,@order_no,@p_totENDCLOSEget_totDEALLOCATEget_totIF@count=0SELECT0ELSESELECT業(yè)務(wù)員銷售總金額=@sumEND第34頁②執(zhí)行存儲(chǔ)過程

EXECemp_tot'張小娟'本例中,先建立一個(gè)游標(biāo)用于臨時(shí)儲(chǔ)存業(yè)務(wù)員的基本銷售信息,包括:業(yè)務(wù)員姓名、客戶編號(hào)、訂單編號(hào)、訂單銷售金額;再利用游標(biāo)能逐行提取的功能,提取游標(biāo)中每一記錄,同時(shí)輸出這些信息;最后統(tǒng)計(jì)其相應(yīng)定單金額的總額,并輸出訂單總額。第35頁5.2.3實(shí)驗(yàn)內(nèi)容在訂單數(shù)據(jù)庫OrderDB中請(qǐng)完成以下實(shí)驗(yàn)內(nèi)容:

(1)根據(jù)訂單明細(xì)表中的數(shù)據(jù),利用游標(biāo)修改OrderMaster表中orderSum的值。(2)創(chuàng)建存儲(chǔ)過程,要求:按第2章員工表定義中的CHECK約束自動(dòng)產(chǎn)生員工編號(hào)。該過程的輸入?yún)?shù)為員工入職的年份,輸出參數(shù)是自動(dòng)生成的員工編號(hào),該編號(hào)滿足第2章員工表定義中的CHECK約束,且后三位流水號(hào)等于表中與入職年份相同的員工編號(hào)最大值加1,如:輸入?yún)?shù)為2020,且員工表中該年度最大的編碼是E2020005,自動(dòng)產(chǎn)生的編號(hào)為E20200006;如果該入職年份沒有其他員工,則流水號(hào)為001。第36頁

(3)

創(chuàng)建存儲(chǔ)過程,要求將大客戶(銷售數(shù)量位于前5名的客戶)中熱銷的前3種商品的銷售信息按如下格式輸出:=============大客戶中熱銷的前種商品的銷售信息===========商品編號(hào)

商品名稱

總銷售金額P20200003三星-Galaxy-A949381.00P20200001vivo-X939173.80P20200002中興AXON天機(jī)7(A2017)27891.00

第37頁(4)請(qǐng)使用游標(biāo)和循環(huán)語句創(chuàng)建存儲(chǔ)過程proSearchCustomer,輸入?yún)?shù)為客戶編號(hào),根據(jù)客戶編號(hào)查找該客戶的名稱、住址、總訂單金額以及所有與該客戶有關(guān)的商品銷售信息,并按商品分組輸出,制作日期取系統(tǒng)的當(dāng)前日期,輸出格式如下:===================客戶訂單表====================---------------------------------------------------------------------------------客戶名稱:

興隆股份有限公司

客戶地址:

天津市

總金額:

29986.00--------------------------------------------------------------------------------商品編號(hào)

總數(shù)量

平均價(jià)格

P2020000142798.00P2020000322599.00P2020000543399.00--------------------------------------------------------------------------------報(bào)表制作人

張小娟

制作日期

2022-07-08

(5)請(qǐng)利用游標(biāo)嵌套和循環(huán)語句創(chuàng)建存儲(chǔ)過程proInvoice,輸入?yún)?shù)有兩個(gè),一個(gè)是定單的開始時(shí)間,一個(gè)是定單的結(jié)束時(shí)間,要求根據(jù)輸入的時(shí)間范圍,輸出每個(gè)定單的發(fā)票信息,包括:客戶名稱、定單日期、發(fā)票號(hào)碼、業(yè)務(wù)員名稱、定單總金額及定單明細(xì)信息等,發(fā)票打印日期取系統(tǒng)的當(dāng)前日期,輸出格式如下:業(yè)務(wù)員銷售時(shí)間范圍為:2020-03-01----2020-10-19

==============================通用機(jī)打發(fā)票==============================-----------------------------------------------------------------------------------------------------------------------客戶名稱:興隆股份有限公司

定購日期:2020-03-01發(fā)票號(hào)碼:I000000006-----------------------------------------------------------------------------------------------------------------------商品名稱

數(shù)量

單價(jià)

金額vivo-X942798.0011192.00TCL-D55A630U13399.003399.00----------------------------------------------------------------------------------------------------------------------商品類數(shù):2商品數(shù)量:5合計(jì):14591.00----------------------------------------------------------------------------------------------------------------------定單銷售員:張露

發(fā)票打印日期:2022-07-11----------------------------------------------------------------------------------------------------------------------

==============================通用機(jī)打發(fā)票==============================------------------------------------------------------------------------------------------------------------------------客戶名稱:五一商廈

定購日期:2020-03-02發(fā)票號(hào)碼:I000000007------------------------------------------------------------------------------------------------------------------------商品名稱

數(shù)量

單價(jià)

金額vivo-X922798.005596.00中興AXON天機(jī)7(A13099.003099.00三星-Galaxy-A932599.007797.00-------------------------------------------------------------------------------------------------------------------------商品類數(shù):3商品數(shù)量:6合計(jì):16492.00------------------------------------------------------------------------------------------------------------------------定單銷售員:張小娟

發(fā)票打印日期:2022-07-11------------------------------------------------------------------------------------------------------------------------第39頁5.3實(shí)驗(yàn)十三觸發(fā)器5.3.1實(shí)驗(yàn)?zāi)康呐c要求(1)掌握觸發(fā)器的創(chuàng)建和使用方法。(2)掌握游標(biāo)和觸發(fā)器的綜合應(yīng)用方法。第40頁5.3.2實(shí)驗(yàn)案例[例5.10]刪除觸發(fā)器:編寫一個(gè)允許用戶一次只刪除一條記錄的觸發(fā)器。

CREATETRIGGERTr_EmpONEmployeeFORDELETEAS/*對(duì)表Employee定義一個(gè)刪除觸發(fā)器*/DECLARE@row_cnt

int/*定義變量@row_cnt,用于跟蹤Deleted表中記錄的個(gè)數(shù)*/SELECT@Row_Cnt=Count(*)FROMDeletedIf@row_cnt>1/*判斷Deleted表中記錄的個(gè)數(shù)是否大于1*/BEGINPRINT‘此刪除操作可能會(huì)刪除多條人事表數(shù)據(jù)!!!'ROLLBACKTRANSACTION/*如果Deleted表中記錄的個(gè)數(shù)大于1,事務(wù)回滾*/END第41頁分析:本例中,觸發(fā)器約束了用戶只能對(duì)Employee這張表刪除一次刪除一條記錄。我們可驗(yàn)證觸發(fā)器的作用效果。驗(yàn)證過程如下:(1)DELETEFROMEmployeeWHEREsex='F'在(1)執(zhí)行后,結(jié)果可能出現(xiàn)二種情況:①系統(tǒng)提示:“外鍵約束沖突”錯(cuò)誤。②系統(tǒng)提示:“此刪除操作可能會(huì)刪除多條人事表數(shù)據(jù)!!!”。第①種情況,由于Employee表與其它表建立了外鍵約束關(guān)系,在刪除表中元組時(shí)必須滿足參照完整性約束的要求。只有刪除外鍵約束,在執(zhí)行刪除操作時(shí)才能激活觸發(fā)器。第②中情況,由于解除了外鍵約束后,刪除操作激活觸發(fā)器,但由于刪除的元組多于一個(gè),所以出現(xiàn)正確系統(tǒng)提示信息。第42頁[例5.11]更新觸發(fā)器:請(qǐng)使用游標(biāo)和循環(huán)語句為OrderDetail表建立一個(gè)更新觸發(fā)器updateorderdetail,要求當(dāng)用戶修改定單明細(xì)表中某個(gè)商品的數(shù)量或單價(jià)時(shí)自動(dòng)修改定單主表中的訂單金額。分析:本例中,Deleted和Inserted表結(jié)構(gòu)與OrderDetail表結(jié)構(gòu)相同。如果用戶修改了銷售明細(xì)表中某個(gè)貨品的數(shù)量或單價(jià)時(shí),Deleted表記載了更新前信息,Inserted表記載了更新后信息,本例正是利用這兩張表結(jié)合游標(biāo)將正確的訂單金額修改到定單主表中。用戶同樣可以用UPDATE命令修改OrderDetail從而驗(yàn)證觸發(fā)器的作用。第43頁CREATETRIGGERupdatesaleitemONOrderDetailFORUPDATEAS/*對(duì)表Employee定義一個(gè)更新觸發(fā)器*/IfUPDATE(quantity)ORUPDATE(price)/*判斷對(duì)指定列quantity或price的更新*/BEGIN/*定義兩個(gè)內(nèi)存變量用于跟蹤游標(biāo)中訂單編號(hào)和商品編號(hào)的值*/DECLARE@ordernoint,@productnochar(5)

/*Deleted表中數(shù)據(jù)信息存入到一個(gè)游標(biāo)結(jié)果集中*/

DECLAREcur_orderdetailCURSORFORSELECTorderno,productnoFROMDeletedOPENcur_orderdetail/*打開游標(biāo)*/

BEGINTRANSACTION/*事務(wù)開始*//*提取游標(biāo)中信息并傳遞給變量@orderno,@productno*/FETCHcur_orderdetailINTO@orderno,@productno第44頁WHILE(@@fetch_status=0)/*判斷如果提取成功*/BEGIN/*修改ordermaster中訂單金額的值*/UPDATEordermasterSETordersum=ordersum-D.quantity*D.price+I.quantity*I.priceFROMInsertedI,DeletedDWHEREOrderMaster.orderNo=I.orderNoANDI.orderNo=D.orderNoANDOrderMaster.orderNo=@ordernoANDI.productNo=D.productNoANDI.productNo=@productno/*提取游標(biāo)中信息并傳遞給變量@orderno,@productno*/FETCHcur_orderdetailINTO@orderno,@productnoENDCOMMITTRAN/*事務(wù)提交*/

CLOSEcur_orderdetail/*關(guān)閉游標(biāo)*/DEALLOCATEcur_orderdetail/*釋放游標(biāo)*/END第45頁[例5.12]插入觸發(fā)器:當(dāng)用戶向Employee表插入數(shù)據(jù)時(shí),觸發(fā)器自動(dòng)將該操作者的名稱和操作時(shí)間記錄在一張表內(nèi),以便追蹤。分析:解決這個(gè)問題可以分三步走:①建立跟蹤表CREATETABLETraceEmployee(

useridchar(10)NOTNULL,--用戶標(biāo)識(shí)

OperateDate

datetimeNOTNULL,--操作日期

OperateTypechar(10)NOTNULL,--操作類型

CONSTRAINTtraceemployeepkPRIMARYKEY(userid,OperateDate)--定義主鍵

)/*user常量是SQL-Server中當(dāng)前登陸的用戶標(biāo)識(shí)*/第46頁②建立觸發(fā)器

/*對(duì)表Employee定義一個(gè)更新觸發(fā)器*/CREATETRIGGERemploteeinsertONEmployeeFORINSERTASIfEXIST(SELECT*FROMInserted)INSERTINTOtraceemployeeVALUES(user,getdate(),'INSERT')③驗(yàn)證用戶執(zhí)行INSERTEmployeeVALUES('E2022030','喻人杰','M','19950415','南京市青海路',null,'20220701','辦公室','職員',8000)之后,查看跟蹤表就能找到操作者的相關(guān)信息。本例還可以創(chuàng)建刪除、更新觸發(fā)器以便跟蹤其他用戶對(duì)表Employee的各種操作。由此可見,觸發(fā)器常用于保證完整性,并在一定程度上實(shí)現(xiàn)安全性。如果觸發(fā)器設(shè)計(jì)太多,必然加大系統(tǒng)管理上的開銷,凡是可以用一般的約束限制的,就不要使用觸發(fā)器。第47頁5.3.3實(shí)驗(yàn)內(nèi)容請(qǐng)完成下面實(shí)驗(yàn)內(nèi)容:(1)創(chuàng)建觸發(fā)器,該觸發(fā)器僅允許“dbo”用戶可以刪除Customer表內(nèi)數(shù)據(jù)。(2)編寫一個(gè)更新觸發(fā)器,實(shí)現(xiàn)安全性控制:只有數(shù)據(jù)庫擁有者(dbo)在工作時(shí)間內(nèi)(周一到周五的上午8.30~11.30,下午2.30~5.00)才可以修改員工表中的薪水,且一次只能修改一條記錄,并將薪水修改前后的值添加到審計(jì)表中。(3)創(chuàng)建觸發(fā)器,要求當(dāng)修改Employee表中員工的出生日期或雇傭日期時(shí),必須保證出生日期在雇傭日期之前,且雇傭日期與出生日期之間必須間隔16周年及以上。(4)編寫一個(gè)插入觸發(fā)器,實(shí)現(xiàn)完整性約束:當(dāng)銷售明細(xì)表中插入某產(chǎn)品的銷售數(shù)據(jù)時(shí),如果銷售數(shù)量低于實(shí)際庫存量,則取消產(chǎn)品的當(dāng)次銷售;否則,及時(shí)更新產(chǎn)品庫存數(shù)量,若銷售的產(chǎn)品數(shù)量在本次銷售后庫存量低于該產(chǎn)品最低庫存量,則提示增加庫存信息。第48頁第6章數(shù)據(jù)庫事務(wù)處理數(shù)據(jù)庫系統(tǒng)原理實(shí)驗(yàn)教程第4版第49頁6.1相關(guān)知識(shí)6.1.1SQLServer事務(wù)模式6.1.2事務(wù)定義6.1.3SQL-92隔離級(jí)別6.1.4SQLServer解決方案6.1.5隔離級(jí)別操作案例6.2實(shí)驗(yàn)十四事務(wù)處理6.2.1實(shí)驗(yàn)?zāi)康呐c要求6.2.2實(shí)驗(yàn)案例6.2.3實(shí)驗(yàn)內(nèi)容目錄6.1相關(guān)知識(shí)事務(wù)是具有完整邏輯意義的數(shù)據(jù)庫操作序列的集合事務(wù)必須具備原子性、一致性、隔離性和永久性,稱為ACID特性。這些特性保證一個(gè)事務(wù)的所有操作要么全部執(zhí)行,要么全部撤銷6.1.1SQLServer事務(wù)模式三種事務(wù)模式:顯式事務(wù)。以BEGINTRANSACTION開始,以COMMITTRANSACTION或ROLLBACKTRANSACTION結(jié)束。

隱式事務(wù)。指當(dāng)前事務(wù)提交或回滾后自動(dòng)啟動(dòng)新的事務(wù),不需使用BEGINTRANSACTION啟動(dòng)事務(wù),只需提交和回滾每個(gè)事務(wù)。自動(dòng)定義事務(wù)。當(dāng)一個(gè)SQL語句成功執(zhí)行后自動(dòng)提交,執(zhí)行出錯(cuò)時(shí)自動(dòng)回滾。第50頁6.1.2事務(wù)定義開始事務(wù)格式:BEGINTRANSACTION[transaction_name]功能:執(zhí)行事務(wù)時(shí),SQLServer會(huì)根據(jù)系統(tǒng)設(shè)置的隔離級(jí)別,鎖定其訪問的資源直到事務(wù)結(jié)束。提交事務(wù)格式:COMMITTRANSACTION[transaction_name]

或COMMITWORK功能:標(biāo)記一個(gè)事務(wù)結(jié)束?;貪L事務(wù)格式:ROLLBACKTRANSACTION[transaction_name|checkpoint_name]

或ROLLBACKWORK功能:使事務(wù)回滾到起點(diǎn)或指定的保存點(diǎn)處,也標(biāo)記一個(gè)事務(wù)結(jié)束。設(shè)置保存點(diǎn)格式:SAVETRANSACTION[checkpoint_name]功能:在事務(wù)內(nèi)部設(shè)置保存點(diǎn),以定義事務(wù)可以返回的位置。6.1.3SQL-92隔離級(jí)別隔離級(jí)別是一個(gè)事務(wù)必須與其它事務(wù)進(jìn)行隔離的程度。隔離級(jí)別越低,并發(fā)度越高SQL-92標(biāo)準(zhǔn)包含四種隔離級(jí)別未提交讀(ReadUncommitted):一事務(wù)可能讀取被其它事務(wù)修改但未提交的數(shù)據(jù)讀已提交(ReadCommitted):一事務(wù)每次讀取的數(shù)據(jù)都是已提交事務(wù)修改的數(shù)據(jù),但并不限制其它事務(wù)修改該數(shù)據(jù);可重復(fù)讀(RepeatableRead):一事務(wù)所有SELECT語句讀取的記錄都不能被修改可串行化(Serializable):所有事務(wù)相互之間都完全隔離

并發(fā)問題隔離級(jí)別臟讀不可重復(fù)讀取幻像讀丟失更新未提交讀是是是是提交讀否是是否可重復(fù)讀否否是否可串行讀否否否否隔離級(jí)別與隔離程度保證6.1.4SQLServer解決方案SQLServer通過封鎖機(jī)制支持上述四種隔離級(jí)別,其語法為:SETTRANSACTIONISOLATIONLEVEL{READCOMMITTED|READUNCOMMITTED|REPEATABLEREAD|SERIALIZABLE}設(shè)置會(huì)話級(jí)別的隔離級(jí)別語法:SETTRANSACTIONISOLATIONLEVEL<ISOLATIONNAME>設(shè)置表的隔離級(jí)別語法:SELECT....FROM<TABLE>WITH(<ISOLATIONNAME>)系統(tǒng)默認(rèn)的隔離級(jí)別是READCOMMITTED6.1.5隔離級(jí)別操作案例

需要使用兩個(gè)會(huì)話,新建的兩個(gè)會(huì)話,一個(gè)是會(huì)話52(事務(wù)T1運(yùn)行環(huán)境),另一個(gè)是會(huì)話53(事務(wù)T2運(yùn)行環(huán)境)[例6-1]讀臟數(shù)據(jù)READUNCOMMITTED先在會(huì)話53中執(zhí)行如下命令:后在會(huì)話52中執(zhí)行如下命令:系統(tǒng)默認(rèn)READCOMMITTED,因更新操作使用排他鎖,查詢一直在等待鎖釋放先在會(huì)話52中,輸入如下命令:

SET

TRANSACTION

ISOLATION

LEVEL

READ

UNCOMMITTEDSELECT

*

FROM

ProductClassWHERE

classNo='006'--或者使用表隔離,效果一樣

SELECT

*

FROM

ProductClass

WITH(NOLOCK)WHERE

classNo='006‘運(yùn)行結(jié)果。

后在會(huì)話53中我們輸入命令并運(yùn)行:ROLLBACK

TRANSACTION

然后輸入并運(yùn)行SELECT

*

FROM

ProductClassWHERE

classNo='006‘會(huì)話53讀到的是回滾前的數(shù)據(jù)“冰箱”,會(huì)話52讀到的

“冰箱1”

是一個(gè)臟數(shù)據(jù)。[例6-2]讀提交(默認(rèn)狀態(tài))READCOMMITTED該隔離級(jí)別在讀之前先申請(qǐng)并獲得共享鎖,允許其他讀操作讀取該鎖定的數(shù)據(jù),但寫操作必須等待鎖釋放,讀操作讀完立刻釋放共享鎖。先在會(huì)話53中輸入:BEGIN

TRANSACTIONUPDATE

ProductClass

SET

className='冰箱2'WHERE

classNo='006'SELECT

*

FROM

ProductClassWHERE

classNo='006‘結(jié)果:會(huì)話53的排他鎖鎖住了產(chǎn)品分類表中編號(hào)為‘006’的記錄后在會(huì)話52中將隔離級(jí)別設(shè)置為READCOMMITTED---由于READCOMMITTED需要申請(qǐng)共享鎖,而鎖與會(huì)話53的排他鎖沖突,會(huì)話被堵塞,系統(tǒng)一直在等待會(huì)話53釋放排他鎖才會(huì)有結(jié)果。

SET

TRANSACTION

ISOLATION

LEVEL

READ

COMMITTEDSELECT

*

FROM

ProductClassWHERE

classNo='006'再在會(huì)話53中執(zhí)行命令COMMIT

TRANSACTION會(huì)話53事務(wù)提交,釋放‘006’的排他鎖,此時(shí)會(huì)話52申請(qǐng)共享鎖成功,查到‘006’的名稱為修改后的‘冰箱2’,由于是已提交讀,所以不讀臟數(shù)據(jù)。在會(huì)話53中,將數(shù)據(jù)修改為原先的數(shù)據(jù)BEGIN

TRANSACTIONUPDATE

ProductClass

SET

className='冰箱'WHERE

classNo='006‘在會(huì)話52中再一次執(zhí)行查詢操作:SELECT

*

FROM

ProductClassWHERE

classNo='006'得到的結(jié)果為“冰箱”,在同一個(gè)事務(wù)內(nèi),會(huì)話52兩次讀的結(jié)果不一樣

由于READCOMMITTED讀操作一完成就立即釋放共享鎖,該級(jí)別不能解決可重復(fù)讀的問題[例6-3]可重復(fù)讀REPEATABLEREAD保證在一個(gè)事務(wù)中的兩個(gè)讀操作之間,其他的事務(wù)不能修改當(dāng)前事務(wù)讀取的數(shù)據(jù),該級(jí)別事務(wù)獲得的共享鎖一直保持至事務(wù)完成。先在會(huì)話53中設(shè)置為REPEATABLEREAD,并執(zhí)行查詢命令SET

TRANSACTION

ISOLATION

LEVEL

REPEATABLE

READBEGIN

TRANSACTIONSELECT

*

FROM

ProductClassWHERE

classNo='006'后在會(huì)話52中修改分類號(hào)‘006’的名稱為‘冰箱3’會(huì)話53的隔離級(jí)別REPEATABLEREAD申請(qǐng)的共享鎖一直要保持到事務(wù)結(jié)束,會(huì)話52無法獲取排他鎖,處于等待狀態(tài)在會(huì)話53中執(zhí)行下面語句,然后提交事務(wù):SELECT

*

FROM

ProductClassWHERE

classNo='006'COMMIT

TRANSACTION在會(huì)話53中,兩次讀的數(shù)據(jù)一樣,解決了不可重復(fù)讀的問題,之后會(huì)話52也獲得排它鎖并執(zhí)行更新操作

[例6-4]可序列化SERIALIZABLEREPEATABLEREAD能保證事務(wù)可重復(fù)讀,但是不能解決幻想讀的問題。

先在會(huì)話53中執(zhí)行查詢操作(驗(yàn)證幻想讀),先測(cè)試隔離級(jí)別為REPEATABLEREAD。后在會(huì)話52中執(zhí)行插入操作:

insertOrderDetailvalues('202001090001','P20210003',5,1599.00)返回會(huì)話53重新執(zhí)行查詢操作并提交事務(wù)會(huì)話53中兩次查詢結(jié)果不一致,多出了一條記錄先在會(huì)話53中將事務(wù)隔離級(jí)別設(shè)置為SERIALIZABLE后在會(huì)話52中執(zhí)行:

insertOrderDetailvalues('202001090001','P20210003',5,1599.00)會(huì)話53將表的共享鎖一直持有,會(huì)話52得不到排它鎖,一直等到會(huì)話53釋放共享鎖才可以,這就保證了會(huì)話53不會(huì)出現(xiàn)幻象讀的問題。再返回會(huì)話53,重新執(zhí)行查詢操作并提交事務(wù),兩次都結(jié)果一樣結(jié)論:

二階段封鎖協(xié)議解決可串行化和丟失更新問題,但是沒有解決臟讀和不可重復(fù)讀的問題,要解決這兩個(gè)問題,必須升級(jí)二階段封鎖協(xié)議。READCOMMITTED達(dá)到了嚴(yán)格二階段封鎖協(xié)議,解決臟讀沒解決可重復(fù)讀的問題;REPEATABLEREAD和SERIALIZABLE達(dá)到了強(qiáng)兩階段封鎖協(xié)議,前者沒解決幻像讀而后者解決幻像讀的問題。

從并發(fā)效率講,越高級(jí)別的隔離級(jí)別,其并發(fā)度就越低,SQLSever默認(rèn)READCOMMITTED,保證不讀臟數(shù)據(jù),同時(shí)盡可能提高并發(fā)度。

REPEATABLEREAD和SERIALIZABLE可視具體的應(yīng)用需求來設(shè)置,一般在做大型或關(guān)鍵的統(tǒng)計(jì)報(bào)表可臨時(shí)設(shè)置為這兩種的隔離級(jí)別6.2實(shí)驗(yàn)十四事務(wù)處理6.2.1實(shí)驗(yàn)?zāi)康呐c要求(1)加深對(duì)事務(wù)概念及屬性理解,尤其對(duì)事務(wù)提交、回滾概念及隔離級(jí)別的認(rèn)識(shí)。(2)掌握SQLServer事務(wù)定義方法。(3)學(xué)會(huì)使用保存點(diǎn)機(jī)制設(shè)置回滾點(diǎn)。(4)學(xué)會(huì)設(shè)置事務(wù)的隔離級(jí)別6.2.2實(shí)驗(yàn)案例設(shè)某客戶要求在一訂單上追加購買一種商品,需分別在訂單主表和訂單明細(xì)表上更新相關(guān)信息,可定義為一個(gè)事務(wù)來完成[例6-5]

假設(shè)某客戶要求在訂單“202001090002”上追加購買商品“P20210004”兩件,請(qǐng)定義一個(gè)事務(wù)insertorder1完成數(shù)據(jù)庫更新。BEGINTRANSACTIONinsertorder1/*事務(wù)開始*/INSERTINTOOrderDetailVALUES('202001090002','P20210004',2,500.00)/*向OrderDetail表插入一條新記錄*/IF@@error!=0/*@@error全局變量,若不為0則執(zhí)行失敗*/BEGINPRINT'插入操作錯(cuò)誤!'RETURNENDUPDATEOrderMaster--/*更新OrderMaster表中orderSum的值*/SETorderSum=orderSum+quantity*priceFROMOrderMastera,(SELECTorderNo,quantity,priceFROMorderDetailWHEREorderNo='202001090002'ANDproductNo='P20210004')bWHEREa.orderNo='202001090002'ANDb.orderNo=a.orderNoIF@@error!=0BEGINROLLBACKTRANSACTIONinsertorder1/*事務(wù)回滾*/PRINT'更新操作錯(cuò)誤!'RETURNENDCOMMITTRANSACTIONinsertorder1/*事務(wù)提交*/[例6-6]假設(shè)某客戶要求在訂單“202002190002”上追加購買“P20210003”商品1件,請(qǐng)定義一個(gè)事務(wù)insertorder2完成數(shù)據(jù)庫更新。要求訂單明細(xì)表更新成功后設(shè)置一保存點(diǎn)before_insert_chk。BEGINTRANSACTIONinsertorder2INSERTINTOorderDetailVALUES('202002190002','P20210003',1,900.00)IF@@error!=0BEGINPRINT'插入操作錯(cuò)誤!'RETURNENDSAVETRANSACTIONbefore_insert_chk/*設(shè)置一個(gè)檢查點(diǎn),檢查點(diǎn)命名為before_insert_chk*/UPDATEOrderMasterSETorderSum=orderSum+quantity*priceFROMOrderMastera,(SELECTorderNo,quantity,price

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論