版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
程序員應(yīng)能夠裝配一個(gè)數(shù)據(jù)集并能處理每次查詢一行的數(shù)據(jù)。設(shè)想你推著滿滿一車自選商品到超級(jí)市場(chǎng)的收款臺(tái),要求收款員用條形碼掃描器一次完成全部物品的掃描。收款員絕對(duì)無法控制價(jià)格的計(jì)算。如果沒有逐行處理數(shù)據(jù)的能力,依賴于應(yīng)用程序需求的程序員要像的收款員了。從版本6Oracle實(shí)現(xiàn)了一種過程處理語言,稱為PL/SQL,它使用戶能更容易地完成工作。PL/SQL具有與大多數(shù)其他程序設(shè)計(jì)語言相似的編程結(jié)構(gòu)。有兩種PL/SL版本:一種是數(shù)據(jù)庫(kù)引擎(ngne)部分,另一種是嵌入到許多racle工具中的獨(dú)立引擎,將它們分別稱為數(shù)據(jù)庫(kù)PL/SQL和工具PL/SQL。兩者非常相似,都具有相同的編程結(jié)構(gòu)、語法和邏輯機(jī)制,工具PL/SQL另外增加了用于支持工具需求的語法。例如:在窗體上設(shè)置下壓式按扭,以定位到屏幕的底部,此動(dòng)作可用OraceForms系統(tǒng)中的L/SQL來編程實(shí)現(xiàn)。本章主要討論數(shù)據(jù)庫(kù)PL/QL。Oracle在何處使用PL/SQL用于Internet的PL/SQL在本章的PL/SQL代碼樣例中,將用三個(gè)點(diǎn)(?)來表示省略。此三點(diǎn)并非代碼的組成部分,僅表示此處某些代碼與所介紹的內(nèi)容關(guān)系不大,沒必要列出。可執(zhí)行(Executable)文件是某種計(jì)算機(jī)程序設(shè)計(jì)語言編寫的程序文件。用戶輸入可執(zhí)行字符集(CharacterSet)描述計(jì)算機(jī)語言支持以及報(bào)表中顯示的字符范圍。大多數(shù)程序設(shè)算術(shù)運(yùn)算符(ArithmeticOperator) 關(guān)系運(yùn)算符(RelationalOperator) 個(gè)日期以二者之間的關(guān)系。常見的關(guān)系運(yùn)算符有:>、<、<>等。變量(Variable) Word)在PL/SQL中有特殊的含義。它們被留下來供Oracle使用,不能用數(shù)據(jù)類型(DataType)定義數(shù)據(jù)(或信息)的類別。如日常生活中,我們把信息分為數(shù)值和字符。字符類型包括某個(gè)特定字母表中所有可表示的字符,數(shù)值類型包括由0~9組成的所循環(huán)(Loop)退出條件(ExitCondition)是循環(huán)的一部分,在循環(huán)中測(cè)試數(shù)據(jù)。如果有兩個(gè)不同的數(shù)控制結(jié)構(gòu)(ControlStructure)影響計(jì)算機(jī)程序的處理流程。如果有兩個(gè)不同的數(shù)據(jù)處理對(duì)象(StoredObject)是存放在數(shù)據(jù)庫(kù)里的PL/SQL代碼段,為開發(fā)者所使用,最終用戶將其當(dāng)作Oracle系統(tǒng)的操作。在1.3.1之2“過程組件”中曾提到過Oracle的這種過程性功能。過程(Procedure)是一個(gè)在數(shù)據(jù)庫(kù)中命名了的PL/SQL集合。它可以或不包含輸入輸函數(shù)也是在數(shù)據(jù)庫(kù)中的PL/SQL集合。與過程的主要區(qū)別是函數(shù)必須有一個(gè)返回值包(Package)是根據(jù)相同功能的特點(diǎn)把過程和函數(shù)在一起的集合。所有的內(nèi)部過程數(shù)據(jù)庫(kù)觸發(fā)器(DatabaseTrigger)也是的可執(zhí)行PL/SQL。數(shù)據(jù)庫(kù)觸發(fā)器在插入、更改或刪除語句之前或之后運(yùn)行。這些數(shù)據(jù)語言(DML)的語句在第7章中討論過。Oracle應(yīng)用服務(wù)器(OracleApplicationServer,縮寫為OAS)是一個(gè)Oracle數(shù)據(jù)庫(kù)的附加工具。OAS可用來建立基于eb的數(shù)據(jù)庫(kù)應(yīng)用并可以在eb請(qǐng)求、PL/SQL引擎和數(shù)據(jù)庫(kù)之間作為主要的引擎。HTML(HypertextMarkupLanguage)是基于Web瀏覽的Internet標(biāo)準(zhǔn)語言。文本和圖形HTML標(biāo)記用來標(biāo)識(shí)HTML文檔。標(biāo)記作為命令傳給Web瀏覽器,例如標(biāo)識(shí)哪個(gè)文本頁(DynamicWebPage)是一個(gè)用命令建立的HTML文檔。在OAS中,它通常是WYSIWYG是Web服務(wù)器可寫入或讀出的與Wb瀏覽器有關(guān)的文本字符串。在眾多的應(yīng)用中,用來控制eb和應(yīng)的計(jì)。持久連接是指應(yīng)用與數(shù)據(jù)庫(kù)之間的一種聯(lián)接狀態(tài)。前端事務(wù)應(yīng)用當(dāng)用戶完成一個(gè)從表單到表單的導(dǎo)航時(shí)通常保持一個(gè)與數(shù)據(jù)庫(kù)連續(xù)連接。Web網(wǎng)頁的請(qǐng)求結(jié)果是一個(gè)不需要與數(shù)據(jù)庫(kù)持久連接的HTML文檔。的使用是用戶學(xué)習(xí)模仿持久連接的一個(gè)方法。為什么要學(xué)習(xí)作者當(dāng)初剛使用PL/SQL時(shí),在盤上找一個(gè)名為plsql己嘗試著用SQL*Plus編寫了一個(gè)PL/SQL模塊,獲得了成功。不過學(xué)習(xí)PL/SQL,提高自己技能的最佳途徑是使用OracleForms或其前一代產(chǎn)品SQL*Forms版本。在使用Oracle的過程中,數(shù)據(jù)庫(kù)觸發(fā)器、打包和函數(shù)都要用PL/SQL編寫代碼。因此,如果不了解PL/SQL就不可能深入掌握Oracle。PL/SQ是應(yīng)用下列Oracle工具編程的基礎(chǔ):OracleOracleOracleOracleApplication如果用戶想熟練地使用Oracle產(chǎn)品,就必須掌握PL/SQL。如果用戶具有使用Ada編程的經(jīng)驗(yàn),對(duì)PL/SQL就不會(huì)陌生。本章介紹了初步的概念和編程結(jié)構(gòu)。只有在更熟悉PL/SQL后,和所有其他程序設(shè)計(jì)語言一樣,PL/SQL也有一個(gè)字符集。用戶能從鍵盤上輸入的字符都數(shù)字0~9符號(hào):()+-*/=!~;:.'@"#$^&_|{}[]其中一些字符用于編程,另一些用作算術(shù)運(yùn)算操作符(除法、加法、冪等)及關(guān)系運(yùn)算符(等于和不等于)。例如:在通信應(yīng)用程序中,開發(fā)人員可能會(huì)使用變量名“area_code”存放下面列出了PL/SQL中常用的算術(shù)運(yùn)算符,如果用戶使用過其他高級(jí)程序設(shè)計(jì)語言,想必不會(huì)陌生。運(yùn)算 意 下面列出了PL/SQL中常用的關(guān)系運(yùn)算符,如果用戶使用過其他程序設(shè)計(jì)語言,一定見過這些符號(hào):運(yùn)算 意 符號(hào)意義樣例(;.項(xiàng)分隔(在例子中,分隔account與Select*from'ifvar1=Rec_read:=--Thisisa/*This,too,isa 變量必須以字母(A~Z)其后跟可選的一個(gè)或多個(gè)字母、數(shù)字(0~9)或特殊字符$、#或_變量長(zhǎng)度不超過30先來看幾個(gè)實(shí)例。表8-2給出了樣例變量名并評(píng)價(jià)了其 變量 合法 特殊字符只能是變量 合法 love多于30 保留字可視為PL/SQL 的字符串。在定義變量名時(shí),用戶不能使用這些保留字“l(fā)oop”在PL/SQL中有特殊含義,因此下列代碼是的:employeevarchar2(0)loopnumber保留字不能用作變量名。盡管我們不推薦,但如果用戶愿意,也可以連接兩個(gè)保留字形成變量名(如loop_varchar2。完整的PL/SQL保留字表可以在Oracle8i文檔中找到。到目前為止,討論了在PL/SQL中編程時(shí)允許使用的字符、變量名和保留字。下面著重討論數(shù)據(jù)類型。PLSQL程序用于處理和顯示多種類型的數(shù)據(jù)。和所有計(jì)算機(jī)軟件一樣,Oracle也將數(shù)據(jù)類型分成大量的子類。例如:數(shù)可分為整型(不允許有小數(shù))和小數(shù)(有一位小數(shù)variable_namevarchar2(max_length);vc_fieldvc_fieldvarchar2(10):='STARTVALUE'num_fieldnumber(precision scale);其中 可以有1~38個(gè)數(shù)字位,而scale表示在precision位數(shù)字中小數(shù)點(diǎn)后的數(shù)num_fieldnumber(12,2表示num_field是一個(gè)整數(shù)部分最多10位、小數(shù)部分最多2date_fielddate,Oracle以DD-MON-YY, 年月日顯示為-SEP-0。PL/SQL中編程處理日期必須使用這種格式。是否可以說用戶必須用數(shù)據(jù)庫(kù)缺省的日期格式除非用戶用O_CHAR或TO_DATE?是否能提醒用戶用自己的TO_DATE/O_CHAR定義的格式而不賴缺省的期式?那使用程序方和更少依于init.ora設(shè)置。 Oracle中還有DD-MON-RR的日期格式,用來表示4位年份以確保Oracle不會(huì)省去兩位數(shù)。關(guān)于這種表示的詳細(xì)情況請(qǐng)參閱SQL*Plus文檔集。這種數(shù)據(jù)類型只有兩個(gè)值:true或false。在使用boolean變量時(shí),如果為true,則做某事,否則做另外的事。例如,如果試圖某公司是否分發(fā)了一個(gè)10KB的2000年年度預(yù)算表,可用boolean變量。若該公司分發(fā)了此表,則該變量值為true。下面討論P(yáng)L/SQL是如何構(gòu)成的。利用前幾節(jié)學(xué)到的知識(shí),我們可以建立一些生動(dòng)有趣的代碼實(shí)例。PL/SQL提供了一組標(biāo)準(zhǔn)的自從計(jì)算機(jī)出現(xiàn)以來,開發(fā)人員一直在使用的過程化技術(shù):邏輯、循環(huán)以及錯(cuò)誤處理機(jī)制。變量PL/SQL程序是由獨(dú)的量執(zhí)代碼和常理等部代塊寫成。PL/SQ可在SQL*Plus窗口中作為一個(gè)的塊編碼。當(dāng)在數(shù)據(jù)庫(kù)中PL/SQL時(shí),子程序包括單元命名的頭部分、程序類型的以及可選的in、out和inoutbegin和enddeclare和exception部分是可選的。 createorrecper/生時(shí)的程序流程以后,PL/SQL的好處將變得更明顯。這將在8.7.4“異?!辈糠钟懻摗I踔猎诒籧reateorreceprocedure(pharmacy_idin
/從Oracle8i開始,Oracle已經(jīng)引進(jìn)了自主的事務(wù)處理。在PL/SQL的早期版本中,在子程序中的commit和rollback名PL/SQL塊、過程、函數(shù)或者數(shù)據(jù)庫(kù)觸發(fā)器的部分增加一個(gè)自主的事務(wù)語句,保證一個(gè)在那個(gè)塊的commit或rollback語句將對(duì)從初始化塊開始的未完成的事務(wù)沒有影響。一個(gè)塊中的自主事務(wù)只能由第一個(gè)部分組成,自主事務(wù)不允許任何嵌套。下面的例子說明了怎樣創(chuàng)建一個(gè)自主事務(wù)塊:pramaautonomous_transaction;/ 此PL/SQL塊用于定義變量。如果用戶熟悉COBOL語言,declare段就相當(dāng)于COBOL中的工作區(qū)。在declare段中,可找到前面講過的常用數(shù)據(jù)類型以及下一節(jié)要介紹的cursor(游標(biāo))當(dāng)對(duì)象(命名塊)產(chǎn)生時(shí),declare段自動(dòng)跟著as關(guān)鍵字。在SQL*Plus編寫一個(gè)PL/SQL代碼塊(塊)時(shí),用戶必須指定DECLARE。createor ceproceduresamp(i_salaryini_cityin datesysdate-;變量能在此初始化status_flagvarchar2(1);mess_textvarchar2(80);temp_buffercursormy_cursorselectemployee_number,last_name,first_namefromemployeea,departmentbwherea.department_number=b.department_numberanda.salary>i_salaryandb.location=i_city;/控制結(jié)構(gòu)是所有程序設(shè)計(jì)語言的。因?yàn)榻^大多數(shù)系統(tǒng)都用于處理各種不同的情況,三種類型的if1.1. 知“更換執(zhí)照請(qǐng)到12-G房間”。而在12-G房間,又得到指示“用現(xiàn)金或保付支票(Certifiedcheck)付帳的在1臺(tái)及2 策的程序控制如表8-3所示。表8-3下一步 2.iftrue,做某事;為FALSE,做另一件不同的事。PLSQL提供三種if邏輯結(jié)構(gòu)供用戶測(cè)試測(cè)試為false,則程序控制轉(zhuǎn)到測(cè)試后面的代碼。下面的代碼說明PL/SQL這個(gè)邏輯的實(shí)現(xiàn):ifvar1>10thenvar2:=var1+20;end語句中的測(cè)試(>)是在8.“PL/SQl字符集”中講過的關(guān)系運(yùn)算符。上面的語句也可以用下列語句替換,結(jié)果一樣。ifnot(var1<=10)thenvar2:=var1+20;endifvar1>10ifvar2<var1thenvar2:=endif;注意,上面代碼中的兩個(gè)endif,分別對(duì)應(yīng)兩個(gè)不同的if。在PL/SQL中實(shí)現(xiàn)if邏輯有兩條規(guī)則每個(gè)if語句塊以相應(yīng)的endif這種結(jié)構(gòu)與if語句非常相似,唯一不同的是在條件為false時(shí),執(zhí)行跟在else后的一條或多ifvar1>10thenvar2:=var1+20;var2:=var1*var1;endif;注意,同樣的控制邏輯也可以用另外的方式表達(dá),使var1+20在else部分執(zhí)行,而var1的ifvar1<=10thenvar2:=var1*var1;var2:=var1+20;endif;這種結(jié)構(gòu)用于替代嵌套if-then-else結(jié)構(gòu)。前面中的嵌套if-then-else語句可改寫為elsif無匹配的endifendif仿佛針對(duì)前面的ifvar1>10thenvar2:=var1+20;elsifvar1between7and8thenvar2:=2*var1;end if屬于本語句塊開始的if,而不屬于elsif關(guān)鍵字。注意上列各 注意 我們建議用戶編寫程序代碼時(shí)采用縮進(jìn)格式—跟上和理解邏輯和控制流是比較容易。前面的例子只說明了一個(gè)elsif的語句。但是,在任何if語句中可以有許多elsif語句。值得注意的是elseelsif語句的if/*Codesegment1-易讀ifvar1<5thenvar2:='y';elsifvar1=5thenvar2:=elsevar2:=null;end /*Codesegment2易讀*/ifvar1<5thenvar2y elseifvar1=5:=nulendif;
對(duì)前面舉過的駕照管理部門DMVPLSQL編程表示其邏輯如下。根據(jù)“the_act12a,12b,12g3.循環(huán)提供了一遍又一遍直至完成執(zhí)行同一個(gè)處理過程的能力。在現(xiàn)實(shí)生活中,從自己的車上卸下雜貨的過程中就有兩個(gè)循環(huán):第一個(gè)是將好幾個(gè)雜貨包一個(gè)一個(gè)搬到家中的重復(fù)動(dòng)168-4所示的邏輯。設(shè)置進(jìn)入循環(huán)的條件(2結(jié)束循環(huán)條件為真(如YES=55YES=設(shè)置退出條件(如22編寫循環(huán)語句時(shí),要注意的問題是一定要確保在退出條件滿足時(shí)有相應(yīng)的退出代碼。遺憾的是,很多時(shí)候開發(fā)人員還是寫了無終止的循環(huán)(當(dāng)然,我們沒有犯過這樣的錯(cuò)誤,但我們)。在洗發(fā)液說明書上可以見到一個(gè)沒有循環(huán)結(jié)束的很好例子:沖洗、抹上、再來。在一個(gè)聯(lián)機(jī)技術(shù)詞典中有一個(gè)非常精辟的總結(jié)說明循環(huán)的概念和開發(fā)人員最容易犯的錯(cuò)誤:(1)LOOP-EXIT-END ifcnt>=100then測(cè)試cnt end End (2)LOOP-EXITWHEN-END10end whilecnt100loopwhile End 第三部分:關(guān)鍵字endlooforin部分定義循環(huán)的變量endloopforcntin1..3insertintotablvalues('Stillinloop',cnt);endloop;在本章的前面部分,討論了PL/SQL塊結(jié)構(gòu)化編碼,介紹了在每個(gè)代碼塊中可以選擇的異無論何時(shí)發(fā)生錯(cuò)誤,控制自動(dòng)地轉(zhuǎn)向執(zhí)行異常部分。表8-5PL/SQL異常, 如果一個(gè)select 檢測(cè)到有多行數(shù)據(jù)存在(有關(guān)隱式游標(biāo)參閱8.8.2“隱式游標(biāo)”) dup_val_on_index 如果某索引中已有某鍵列值,若還要在該索引中創(chuàng)建該鍵碼值的索引項(xiàng)時(shí),出現(xiàn)此異常。例如:假設(shè)一個(gè)計(jì)費(fèi)系統(tǒng)以號(hào)為鍵碼,當(dāng)某個(gè)應(yīng)用程序準(zhǔn)備創(chuàng)建一個(gè)重復(fù)的號(hào)時(shí),產(chǎn)生此異常value_error 此異常表示指定目標(biāo)域的長(zhǎng)度小于待放入其中的數(shù)據(jù)的長(zhǎng)度。例如:ABCDEFGH”字符串放入定義為“varchar2(6)”的域時(shí),產(chǎn)生此異常當(dāng)遇到預(yù)先定義的錯(cuò)誤時(shí),錯(cuò)誤被當(dāng)前塊的異常部分相應(yīng)的when...then語句捕捉。跟在when句子后的then語句的代碼被執(zhí)行。then語句執(zhí)行后,控制運(yùn)行到了緊跟著當(dāng)前塊的end語句的行。如果你的錯(cuò)誤陷阱代碼只是退出內(nèi)部嵌套的塊,程序?qū)⒗^續(xù)執(zhí)行跟在內(nèi)部塊end語句如果在當(dāng)前塊中沒有聯(lián)系錯(cuò)誤的when子句并且begin/end塊是嵌套的,程序?qū)⒗^續(xù)在外部塊中尋找錯(cuò)誤處理柄,直到找到一個(gè)。當(dāng)錯(cuò)誤發(fā)生而在任何異常部分沒有與之聯(lián)系的錯(cuò)誤處理柄,程序?qū)⒔K止。Oracle給我們提供了“抓住一切”的錯(cuò)誤處理柄來捕捉不是預(yù)定義的錯(cuò)誤。whenothersthen錯(cuò)誤處理柄將捕捉所有Oracle預(yù)定義錯(cuò)誤范圍之外的錯(cuò)誤。通過Oracle的sqlcode和sqlerrm函數(shù)在whenothersthen錯(cuò)誤處理柄中顯示錯(cuò)誤代碼和錯(cuò)誤信息是一個(gè)好主意。規(guī)則通常用一個(gè)whenothers錯(cuò)誤處理柄。如果你在異常部分有其他的錯(cuò)誤處理柄,確定whenothers是最后一個(gè)。如果你錯(cuò)誤地先寫whenothers子句,它將捕捉所有的錯(cuò)誤,即使是那些 有時(shí),特別是在使用if邏輯時(shí),用戶結(jié)束測(cè)試一個(gè)條件。當(dāng)測(cè)試條件為true,什么工作都ifcnt>=90theninsertintotab1values('Stilllessthan90',cnt);endif;關(guān)鍵字nullnull”結(jié)構(gòu)常用于捕捉某個(gè)異常,但不做任何處理,然后繼續(xù)執(zhí)行下一塊代碼而不終止程序單元。PL/SQL用游標(biāo)來管理SQ的select語句。游標(biāo)是為處理這些語句而分配的一大塊內(nèi)存。有時(shí)用戶手工定義游標(biāo)。游標(biāo)定義類似于其他PL/SQL變量,并且必須遵守同樣名規(guī)則。在本節(jié)中,介紹顯式游標(biāo)(ExplicitCursor)和隱式游標(biāo)(ImplicitCursor)。顯式游標(biāo)要(Declare),在使用前要打開(Open),使用完畢要關(guān)閉(Close)。使用隱式游標(biāo)時(shí),用戶無需執(zhí)行上述步驟,只要簡(jiǎn)單地編碼select語句并讓PL/SQL根據(jù)需要處理游標(biāo)即可。與循環(huán)結(jié)構(gòu)結(jié)合的顯式游標(biāo)處理返回多于一行的Select語句。與循環(huán)結(jié)合的游標(biāo)將允許你顯式游標(biāo)是作為declare段中的一部分進(jìn)行定義的。所定義的SQL語句必須只包含select語句,并且不能用insert、update或delete關(guān)鍵字。當(dāng)select語句可能返回零或多于一行時(shí),必須用顯式游標(biāo)。本節(jié)介紹如下內(nèi)容:準(zhǔn)備(或打開) 表中,first_name,last_namearchar2(20)而ssn是fnamevarchar2(10);lnamevarchar2(30);ssec_numvarchar2(8);cursorregion_curisselectfirst_name,last_name,ssnwhereregion_number=region_number_in;openfetchregion_curintofname,lname,ssec_num;whileregion_cur%foundifssec_numisnullinsertintoe_msgvalues(pin_in,'noinsertintoe_tabvalues(pin_in,sysdate);endif;fetchregion_curintofname,lname,ssec_num;endloop;closeregion_cur;/found”和“%notfound”檢驗(yàn)游標(biāo)(此處為“mycur”)成功與否。如果游標(biāo)按照ifmycur%foundendifmycur%notfoundendfetchmycurintotemp_buffer;closemycur;ifmycur%foundend循環(huán)執(zhí)行游標(biāo)取數(shù)操作時(shí),檢索出的總數(shù)據(jù)行數(shù)存放在系統(tǒng)變量“%rowcountwhilecounter<100fetchmycurintotemp_buffer;ifmycur%rowcount<=50thenendcounter:=counter+1;endloop;openmycur;fetchmycur;ifmycur%foundcursormycurselect /*in是數(shù)字型* /*Last_name是字符型*fromwherepin=pin_in;field1varchar2(10);field2number;openfetchmycurintocursormycurselect fromwherepin=pin_in;field1varchar2(10);field2number;openfetchmycurinto如果試圖打開一個(gè)已打開的游標(biāo)或關(guān)閉一個(gè)已關(guān)閉的游標(biāo),將會(huì)出現(xiàn)錯(cuò)誤。因此用戶在打開或關(guān)閉游標(biāo)前,若不清楚其狀態(tài),應(yīng)該用“%isopentrue或false,采取相應(yīng)的動(dòng)作。ifmycur%isopenthenopenmycur;endif;游標(biāo)的for缺了游標(biāo)的for循環(huán)的簡(jiǎn)單介紹,這節(jié)不能算完全。這部分要求用戶忽視剛剛了解的顯式游標(biāo)。游標(biāo)的for循環(huán)的優(yōu)點(diǎn)是用戶不需打開游標(biāo)、取數(shù)據(jù)、測(cè)試數(shù)據(jù)的存在(%found)游標(biāo)或定義存放數(shù)據(jù)的變量。相同之處是在部分中的游標(biāo)定義。當(dāng)游標(biāo)被調(diào)用時(shí),用Select語句中的同樣一些元素創(chuàng)建一條記錄。對(duì)于由游標(biāo)檢索出的每一行繼續(xù)執(zhí)行循環(huán)內(nèi)的全部代碼,當(dāng)沒有數(shù)據(jù)發(fā)現(xiàn)時(shí),游標(biāo)自動(dòng)地關(guān)閉。該方法要求最少的編程和得到很少游標(biāo)結(jié)構(gòu)前面的例子用游標(biāo)的forcursorregion_curselectfirst_name,last_name,ssnwhereregion_number=region_number_in;forregion_recinregion_curifregion_rec.ssnisnullinsertintoe_msgvalues(pin_in,'nossnum');insertintoe_tabvalues(pin_in,sysdate);endif;endloop;/ifcounter>=20thenselectlast_nameintolnamewherepin=/每個(gè)隱式游標(biāo)必須有一個(gè)intoifthis_value>0selectcount(*)from endif;ifthis_value>0selectcount(*)intocnterfrom endif;和顯式游標(biāo)一樣,帶有關(guān)鍵字“隱式游標(biāo)一次僅返回一行,使用時(shí)必須檢查表 8-5給出的異常。最常見的異常為“too_many_rowsifcounter>=10thenselectageintov_agewherepin=pin_value;whentoo_many_rowsinsertintotabavalues(pin_value,sysdate);whenno_data_foundthenend/通過檢查PL/SQL的系統(tǒng)變量“%found”或“%notfound”確認(rèn)成功或失敗。使用顯式游標(biāo)的代碼段簡(jiǎn)單地檢測(cè)這些系統(tǒng)變量以確定使用顯示游標(biāo)的select語句成功或失敗。在學(xué)習(xí)關(guān)系數(shù)據(jù)庫(kù)理論時(shí),很有趣的是,由兩個(gè)或多個(gè)表聯(lián)接構(gòu)成的查詢結(jié)果本身就是一個(gè)表。常常需要用PL/SQL循環(huán)查詢一組數(shù)據(jù)并對(duì)一組查詢值進(jìn)行比較。PL/SQL允許將這少的I/O操作。本書很多地方都談到了數(shù)據(jù)類型—字符、字母數(shù)字、數(shù)值等等。而PL/SQL表卻是用一個(gè)用戶定類表來說的考查下程,看看了找目的怎將州裝入內(nèi)的。setserveroutputonsize100000typejust_namesistableofindexbybinary_integer局部表just_name包含了和stateibinary_integer:= nametabforstate_rec (selectnamefromstate)i:=nametab(i):=state_;endloop;/注意PL/SQL表為PL/SQL的版本2.3PL/SQL是SQL*Plus和過程化代碼共同構(gòu)成的一個(gè)混合體。注釋文本括在斜杠星號(hào)(/*declaretfieldvarchar2(20);selectdesc_textintotfieldfromprod /*prod是一個(gè)中心查詢*/wherepnum='FR4512';/*表的擁有者為 /或declaretfieldvarchar2(20);selectdesc_textintotfieldfrom wherepnum='FR4512'; /或declaretfieldvarchar2(20);selectintotfieldfromprodwherepnum='FR4512';/createorreceprocedure(order_number_inincursordetail_curselectproduct_number,tyfromorder_detailwhereorder_number=order_number_in;v_product_numbernumber;v_tynumber;openfetchdetail_curintov_product_number,v_ty;whiledetail_cur%foundifv_ty>100insertintoorder_audit(order_number,product_number,ty)values(order_number_in,v_product_number,v_ty);endif;"if""Endif"結(jié)束fetchdetail_curintoend/Oracle給開發(fā)者提供了更容易的工具集合。其中一個(gè)例子就是有許多適合編程人員的內(nèi)置程序包。內(nèi)置程序包是預(yù)先生成的、在數(shù)據(jù)庫(kù)中、能在PL/SQL代碼塊中調(diào)用的根據(jù)需求可以傳遞參數(shù)的程序,它們用來完成下面的各種任務(wù):把結(jié)果輸出到終端窗口(dbms_output)直接從操作系統(tǒng)文件讀寫數(shù)據(jù)(utl_file)執(zhí)行動(dòng)態(tài)的SQL(dbms_sql)PL/SQL的功能在于許多預(yù)先寫好的過程。在8.14.2中的“動(dòng)態(tài)HTML概念”部分,將演示怎樣用Web開發(fā)工具中的內(nèi)置程序包創(chuàng)建頁。當(dāng)Oracle編譯PL/SQL塊時(shí),可能會(huì)提示一些錯(cuò)誤。如同我們面中所表示的,斜杠(/)結(jié)束PL/SQL塊,并且傳遞代碼至Oracle。參閱下述出錯(cuò)編譯,注意PL/SQL編譯時(shí)并不顯示錯(cuò)誤,要顯示錯(cuò)誤可用語句shoerrors。sql>createor ceproceduretemp(countinnumber)declarecursormycurselectcount(*)fromopenfetch/warning:Procedurecreatedwithcompilationerrors.SQI>shoerrorsErrorsforPROCEDURELINE/COL PLS-00103:Encounteredthesymbol";"whenexpectingoneofthebegindeclareexitforgotoifloopmodnullpragmaraisereturnselectupdatewhile<anidentifier><adouble_quoteddelimited-identifier><abindvariable><<closecurrentdeletefetchlockinsertopenrollbacksavepointsetsqlexecutecommitforall<asingle-quotedSQLsql>createor ceproceduretemp(countinnumber)declarecursormycurselectcount(*)fromopenfetchwarning:ProcedurecreatedwithcompilationSQL>shoerrorsErrorsforPROCEDURETEMP:LINE/COLERROR
PLS-00103:Encounteredthesymbo;l”whenexpectingoneof.into下面將給出三個(gè)簡(jiǎn)單的需求,并示范如何用PL/SQL來完成。每個(gè)例子中的注釋說明了在本章講過的一些要點(diǎn)。我們用到的編碼風(fēng)格同時(shí)說明了良好的編碼技巧。Oracle的保留字已經(jīng)實(shí)例本例將通過社會(huì)號(hào)碼查詢其出生日期。注釋代碼說明PL/SQL如何工作。例中使createorre ceprocedureget_dob(ss_numvarchar2,doboutdate)select
into wheresoc_sec_num=ss_num;exceptionwhenno_data_foundthen /定義的過程有兩個(gè)包含在括號(hào)中的變量,第一個(gè)包括要查詢其出生日期的人員的社會(huì)保險(xiǎn)號(hào),第二個(gè)接受出生日期并將其返回給本過程的調(diào)用者。注意在begin和createorreceprocedureas代碼行間無分號(hào)。此兩行間不允許有分號(hào)實(shí)例本例用函數(shù)而非過程達(dá)到上述相同的結(jié)果。正如下列所示,函數(shù)可以接受多個(gè)變量procedure換成了function。createorre cefunctionget_dob(ss_numvarchar2)returndateselectintobirthd wheresoc_sec_num=ss_num;whenno_data_foundthenerror_notify(ss_num);-birthd:=whenothersreturn 實(shí)例由于區(qū)域代碼(AreaCode)分成片段(Piece),某些編號(hào)仍然是舊的代碼,而某些已是新的。我createorreceprocedureac_switch(oacinnacinl_change_swnumber(3); cursorac_curSelectdistinctpref_3fromwherearea_code=oac;forac_recinac_curl_change_it:='N';selectintol_change_swfromstatic_excwhereareacode=
andpref_3=ac_rec.pref_3;whenno_data_foundl_change_it:=ifl_change_it='Y'
updatesetarea_code=nacwherearea_code=andpref_3=ac_rec.pref_3;endif;endloop;/
注意在游標(biāo)時(shí)distinct的使用。有的讀者可能熟悉關(guān)鍵字unique,但它只用在forac_recinac_curloop語句連續(xù)取每次與查詢語句中的謂詞匹配的行存放到ac_recstatic_exc的select語句包含在自身的內(nèi)部beginend塊內(nèi),當(dāng)需要在隱式游標(biāo)中檢查一個(gè)或多個(gè)異常時(shí)可以這樣來進(jìn)行。用于Internet的這節(jié)打算簡(jiǎn)潔地接觸Oracle應(yīng)用程序服務(wù)器和怎樣編寫PL/SQL代碼,這種代碼把動(dòng)態(tài)HTML文檔返回到客戶端Web。PL/SQL存放在數(shù)據(jù)庫(kù)中。它是一個(gè)應(yīng)用邏輯和產(chǎn)生HTML、這節(jié)從通過給出一個(gè)對(duì)HTML的綜述開始,它是什么和它怎樣解釋。隨著對(duì)HTML基礎(chǔ)的理解,這節(jié)剩余部分將試圖使你熟悉工具和產(chǎn)生頁的方法。通過融合你的PL/SQL、游標(biāo)和HTML知識(shí),產(chǎn)生一個(gè)從數(shù)據(jù)庫(kù)中獲得與一個(gè)傳遞參數(shù)值相匹配的數(shù)據(jù)的應(yīng)用程序來結(jié)束本節(jié)。HTML入被eb瀏覽器翻譯成格式化和顯示信息。回憶PC字處理時(shí)代的早期,在indows的所見即所得的環(huán)境之前,如果看文檔的代碼,你可能已經(jīng)看到了“粗體開始”前和一個(gè)“粗體結(jié)束”后的文本將以粗體打印。這種標(biāo)識(shí)文檔的方法用來幫助員工決定打印的文檔看起來像什么。HTML用同樣的方法標(biāo)識(shí)文本文檔。它用任何文本編輯器和本機(jī)標(biāo)識(shí)語言來寫。同樣,eb編寫軟件也能進(jìn)行簡(jiǎn)單的點(diǎn)擊操作。下一次,你瀏覽網(wǎng)頁,能從瀏覽器菜單里頁源代碼,并能看到各種各樣的圍繞著正在看的文本和圖形的。我們提供的例子可以完全按照你所見到的形式用一個(gè)計(jì)算機(jī)的文本編輯器編寫,然后通過在eb瀏覽器中輸出文件的路徑來顯示。我們有目的地提供一個(gè)沒有精美的背景和圖象的例子,使你可以親自嘗試一下:圖8-1顯示了HTML代碼在Web瀏覽器如何出現(xiàn)。在繼續(xù)本節(jié)的創(chuàng)建動(dòng)態(tài)HTML之前,下通常成對(duì)出現(xiàn),封裝被格式化的文本和圖形。第一個(gè)定義了標(biāo)識(shí)的開始點(diǎn),第二個(gè)定了格式到里結(jié)束例以<html>是HTML。在文本文件的最后一行可以發(fā)現(xiàn)是</html>,在這里結(jié)束了eb瀏覽器翻譯的HTML。為了在HTM文檔中專業(yè)化地布置和排列文本和圖形,表格是必不可少的。簡(jiǎn)單地說,表格是一個(gè)網(wǎng)格,有產(chǎn)生插入文本和圖形的單元格的行和列。我們的例子甚至在一個(gè)外部表格的單元格中嵌套了一個(gè)表格。表格是通過打開表格<table>和關(guān)閉表格</table>定義的。在表格里,表格的行通過<tr>打開、</tr>關(guān)閉。在行中的列通過表格數(shù)據(jù)定義。表格數(shù)據(jù)打開是<td></td>。在表格數(shù)據(jù)之間,有在文檔中顯示的數(shù)據(jù)(文本、圖形、超鏈等等和支持的任何格式屬性(下劃線、粗體、斜體等等)。圖8-1HTML文檔的Web成功應(yīng)用表格的關(guān)鍵是在以正確的順序中使用。用戶通常是在出現(xiàn)相反順序時(shí)關(guān)閉。因此,表格打開直到所有的表格行和表格數(shù)據(jù)已經(jīng)編碼才能關(guān)閉。下面顯示了一個(gè)簡(jiǎn)單的表格:我們知道能從數(shù)據(jù)庫(kù)中用游標(biāo)一次抽取一行數(shù)據(jù)。想象從數(shù)據(jù)庫(kù)中的數(shù)據(jù)表集生成一個(gè)HTML。通過傳遞“執(zhí)行部門”的工作分類給過程,游標(biāo)能從雇員表中檢索出每個(gè)“執(zhí)行部門”類型的雇員的人事信息并從放假表中檢索出他或假期余額。我們開始討論動(dòng)態(tài)HTMHTML右之間安排它。OracleApplicationServer和PL/SQL是在Oracle數(shù)據(jù)庫(kù)中用發(fā)現(xiàn)的數(shù)據(jù)生成頁的角色。機(jī)智的開發(fā)者將為標(biāo)準(zhǔn)背景、表格布局和導(dǎo)航等等的eb地址生成模板。這些標(biāo)準(zhǔn)能作為每次網(wǎng)頁建立時(shí)調(diào)用的獨(dú)立的模塊。這些獨(dú)立過程的調(diào)用和應(yīng)用邏輯的組合將產(chǎn)生有動(dòng)態(tài)信息的專業(yè)的HTML動(dòng)態(tài)HTML以上出現(xiàn)了“動(dòng)態(tài)”的概念,為了更好地理解它,我們通過對(duì)照“靜態(tài)”概念來解釋它的意思。用戶所的大多數(shù)網(wǎng)頁是靜態(tài)的。當(dāng)用戶在瀏覽器中輸入HTML文檔的URL時(shí),一個(gè)在Web服務(wù)器上的文件,它只有在某個(gè)網(wǎng)絡(luò)管理員在Web服務(wù)器上放置一個(gè)同名的新文件時(shí)才改變內(nèi)容。相反,當(dāng)用戶從URL調(diào)用一個(gè)PL/SQL過程時(shí),依靠數(shù)據(jù)庫(kù)中數(shù)據(jù)的變化或者傳遞參數(shù)的不同,PL/SQL代碼生成HTML文檔,并為每次請(qǐng)求返回可能不同的網(wǎng)頁。Oracle給開發(fā)者提供了一組內(nèi)置程序包,它可產(chǎn)生HTML、發(fā)送或接收文本、生成前端表單等。讓我們介紹幾個(gè)這樣的工具,看看它們?cè)鯓訋椭覀償?shù)據(jù)和作為一個(gè)HTML在應(yīng)用程序服務(wù)器PL/SL代碼中應(yīng)用定義在HTP內(nèi)置程序包的過程,用戶可生成HML和返回一個(gè)Web瀏覽器可以調(diào)用的HML文檔。這里有幾個(gè)HTP打程和一個(gè)在缺少適當(dāng)?shù)腍TP過程的情況下用來傳遞HML字符串的通用過程。下面例子的代碼和輸出說明了HPcreateor ceprocedure(zip_inincursorphrmc_curselectname,contacts,phone_numberfrompharmacywherezip=htp.title('HealthInformationCorporation');htp.bodyopen(cattributes=>'bgcolor=htp.tablecaption('PharmacyInformation','center');htp.tableheader('PharmacyName');htp.tableheader('ContactName');htp.tableheader('PhoneNumber');forphrmc_recinphrmc_curendloop;/在下一節(jié),將演示怎樣在一個(gè)eb表單中調(diào)用這個(gè)過程。下面是一個(gè)前面過程被調(diào)用時(shí)生成HTM的示例。在HTML中出現(xiàn)的(藥房名)、(聯(lián)系人名)、()將依賴zip_in參數(shù)值成HTML的eb瀏覽器顯示結(jié)果。<TITLE>HealthInformation<BODYbgcolor=<TABLE<CAPTIONALIGN="CENTER">Pharmacy<TH>Pharmacy<TH>Contact<TH>Phone<TD>A.B.ThriftDrug<TD>Arlene<TD>MirageMedicalCenter<TD>John<TD>NumberFiveDrug<TD>Mark 每個(gè)人調(diào)用產(chǎn)生相應(yīng)的 、屬性和文本的HTP打包的過程。頁標(biāo)題、標(biāo)題、表頭是硬編碼,因此這頁的每次生成是相同的。 面的例子中,在藥房表中有三個(gè)與輸入的郵政編碼匹配的藥房。由于“游標(biāo)for循環(huán)”代碼完全在一組表的 內(nèi)部,一個(gè)簡(jiǎn)單的HTML一個(gè)每次循環(huán)迭代的表行生成。 htp.tabledata過程調(diào)用內(nèi)部的htp.tablerowopen,ht
溫馨提示
- 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. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版承包工地食堂餐廚垃圾處理合同模板3篇
- 2024蔬菜加工產(chǎn)品銷售合作協(xié)議3篇
- 2024年股權(quán)轉(zhuǎn)讓合同標(biāo)的及屬性詳細(xì)描述
- 2024年版物業(yè)托管服務(wù)協(xié)議版B版
- 二零二五版離婚協(xié)議書起草與審核合同2篇
- 2024版房屋贈(zèng)與合同協(xié)議書大全
- 天津中德應(yīng)用技術(shù)大學(xué)《教育技術(shù)與傳播》2023-2024學(xué)年第一學(xué)期期末試卷
- 二零二五版家政服務(wù)+家庭健康促進(jìn)合同3篇
- 太原幼兒師范高等??茖W(xué)校《西醫(yī)外科學(xué)醫(yī)學(xué)免疫學(xué)與病原生物學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 二零二五年特殊用途變壓器安裝與性能測(cè)試合同2篇
- 迪士尼樂園總體規(guī)劃
- 2024年江蘇省蘇州市中考數(shù)學(xué)試卷含答案
- 2024年世界職業(yè)院校技能大賽高職組“市政管線(道)數(shù)字化施工組”賽項(xiàng)考試題庫(kù)
- 介紹蝴蝶蘭課件
- 大學(xué)計(jì)算機(jī)基礎(chǔ)(第2版) 課件 第1章 計(jì)算機(jī)概述
- 數(shù)字化年終述職報(bào)告
- 《阻燃材料與技術(shù)》課件 第5講 阻燃塑料材料
- 2024年職工普法教育宣講培訓(xùn)課件
- 安保服務(wù)評(píng)分標(biāo)準(zhǔn)
- T-SDLPA 0001-2024 研究型病房建設(shè)和配置標(biāo)準(zhǔn)
- (人教PEP2024版)英語一年級(jí)上冊(cè)Unit 1 教學(xué)課件(新教材)
評(píng)論
0/150
提交評(píng)論