PLSQL是ORACLE對(duì)標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)語(yǔ)言的擴(kuò)展.doc_第1頁(yè)
PLSQL是ORACLE對(duì)標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)語(yǔ)言的擴(kuò)展.doc_第2頁(yè)
PLSQL是ORACLE對(duì)標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)語(yǔ)言的擴(kuò)展.doc_第3頁(yè)
PLSQL是ORACLE對(duì)標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)語(yǔ)言的擴(kuò)展.doc_第4頁(yè)
PLSQL是ORACLE對(duì)標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)語(yǔ)言的擴(kuò)展.doc_第5頁(yè)
已閱讀5頁(yè),還剩79頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

PL/SQL是ORACLE對(duì)標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)語(yǔ)言的擴(kuò)展,ORACLE公司已經(jīng)將PL/SQL整合到ORACLE 服務(wù)器和其他工具中了,近幾年中更多的開(kāi)發(fā)人員和DBA開(kāi)始使用PL/SQL,本文將講述PL/SQL基礎(chǔ)語(yǔ)法,結(jié)構(gòu)和組件、以及如何設(shè)計(jì)并執(zhí)行一個(gè)PL/SQL程序。PL/SQL的優(yōu)點(diǎn)從版本6開(kāi)始PL/SQL就被可靠的整合到ORACLE中了,一旦掌握PL/SQL的優(yōu)點(diǎn)以及其獨(dú)有的數(shù)據(jù)管理的便利性,那么你很難想象ORACLE缺了PL/SQL的情形。PL/SQL 不是一個(gè)獨(dú)立的產(chǎn)品,他是一個(gè)整合到ORACLE服務(wù)器和ORACLE工具中的技術(shù),可以把PL/SQL看作ORACLE服務(wù)器內(nèi)的一個(gè)引擎,sql語(yǔ)句執(zhí)行者處理單個(gè)的sql語(yǔ)句,PL/SQL引擎處理PL/SQL程序塊。當(dāng)PL/SQL程序塊在PL/SQL引擎處理時(shí),ORACLE服務(wù)器中的SQL語(yǔ)句執(zhí)行器處理pl/sql程序塊中的SQL語(yǔ)句。PL/SQL的優(yōu)點(diǎn)如下:. PL/SQL是一種高性能的基于事務(wù)處理的語(yǔ)言,能運(yùn)行在任何ORACLE環(huán)境中,支持所有數(shù)據(jù)處理命令。通過(guò)使用PL/SQL程序單元處理SQL的數(shù)據(jù)定義和數(shù)據(jù)控制元素。. PL/SQL支持所有SQL數(shù)據(jù)類型和所有SQL函數(shù),同時(shí)支持所有ORACLE對(duì)象類型. PL/SQL塊可以被命名和存儲(chǔ)在ORACLE服務(wù)器中,同時(shí)也能被其他的PL/SQL程序或SQL命令調(diào)用,任何客戶/服務(wù)器工具都能訪問(wèn)PL/SQL程序,具有很好的可重用性。. 可以使用ORACLE數(shù)據(jù)工具管理存儲(chǔ)在服務(wù)器中的PL/SQL程序的安全性??梢允跈?quán)或撤銷數(shù)據(jù)庫(kù)其他用戶訪問(wèn)PL/SQL程序的能力。. PL/SQL代碼可以使用任何ASCII文本編輯器編寫(xiě),所以對(duì)任何ORACLE能夠運(yùn)行的操作系統(tǒng)都是非常便利的. 對(duì)于SQL,ORACLE必須在同一時(shí)間處理每一條SQL語(yǔ)句,在網(wǎng)絡(luò)環(huán)境下這就意味作每一個(gè)獨(dú)立的調(diào)用都必須被oracle服務(wù)器處理,這就占用大量的服務(wù)器時(shí)間,同時(shí)導(dǎo)致網(wǎng)絡(luò)擁擠。而PL/SQL是以整個(gè)語(yǔ)句塊發(fā)給服務(wù)器,這就降低了網(wǎng)絡(luò)擁擠。PL/SQL塊結(jié)構(gòu)PL/SQL是一種塊結(jié)構(gòu)的語(yǔ)言,組成PL/SQL程序的單元是邏輯塊,一個(gè)PL/SQL 程序包含了一個(gè)或多個(gè)邏輯塊,每個(gè)塊都可以劃分為三個(gè)部分。與其他語(yǔ)言相同,變量在使用之前必須聲明,PL/SQL提供了獨(dú)立的專門用于處理異常的部分,下面描述了PL/SQL塊的不同部分:聲明部分(Declaration section)聲明部分包含了變量和常量的數(shù)據(jù)類型和初始值。這個(gè)部分是由關(guān)鍵字DECLARE開(kāi)始,如果不需要聲明變量或常量,那么可以忽略這一部分;需要說(shuō)明的是游標(biāo)的聲明也在這一部分。執(zhí)行部分(Executable section)執(zhí)行部分是PL/SQL塊中的指令部分,由關(guān)鍵字BEGIN開(kāi)始,所有的可執(zhí)行語(yǔ)句都放在這一部分,其他的PL/SQL塊也可以放在這一部分。異常處理部分(Exception section)這一部分是可選的,在這一部分中處理異?;蝈e(cuò)誤,對(duì)異常處理的詳細(xì)討論我們?cè)诤竺孢M(jìn)行。PL/SQL塊語(yǔ)法DECLARE-declaration statementsBEGIN-executable statementsEXCEPTION-exception statementsENDPL/SQL塊中的每一條語(yǔ)句都必須以分號(hào)結(jié)束,SQL語(yǔ)句可以使多行的,但分號(hào)表示該語(yǔ)句的結(jié)束。一行中可以有多條SQL語(yǔ)句,他們之間以分號(hào)分隔。每一個(gè)PL/SQL塊由BEGIN或DECLARE開(kāi)始,以END結(jié)束。注釋由-標(biāo)示。PL/SQL塊的命名和匿名PL/SQL程序塊可以是一個(gè)命名的程序塊也可以是一個(gè)匿名程序塊。匿名程序塊可以用在服務(wù)器端也可以用在客戶端。命名程序塊可以出現(xiàn)在其他PL/SQL程序塊的聲明部分,這方面比較明顯的是子程序,子程序可以在執(zhí)行部分引用,也可以在異常處理部分引用。PL/SQL程序塊可背獨(dú)立編譯并存儲(chǔ)在數(shù)據(jù)庫(kù)中,任何與數(shù)據(jù)庫(kù)相連接的應(yīng)用程序都可以訪問(wèn)這些存儲(chǔ)的PL/SQL程序塊。ORACLE提供了四種類型的可存儲(chǔ)的程序:. 函數(shù). 過(guò)程. 包. 觸發(fā)器函數(shù)函數(shù)是命名了的、存儲(chǔ)在數(shù)據(jù)庫(kù)中的PL/SQL程序塊。函數(shù)接受零個(gè)或多個(gè)輸入?yún)?shù),有一個(gè)返回值,返回值的數(shù)據(jù)類型在創(chuàng)建函數(shù)時(shí)定義。定義函數(shù)的語(yǔ)法如下:FUNCTION name parameter,parameter,.) RETURN datatypes ISlocal declarationsBEGINexecute statementsEXCEPTIONexception handlersEND name過(guò)程存儲(chǔ)過(guò)程是一個(gè)PL/SQL程序塊,接受零個(gè)或多個(gè)參數(shù)作為輸入(INPUT)或輸出(OUTPUT)、或既作輸入又作輸出(INOUT),與函數(shù)不同,存儲(chǔ)過(guò)程沒(méi)有返回值,存儲(chǔ)過(guò)程不能由SQL語(yǔ)句直接使用,只能通過(guò)EXECUT命令或PL/SQL程序塊內(nèi)部調(diào)用,定義存儲(chǔ)過(guò)程的語(yǔ)法如下:PROCEDURE name (parameter,parameter,.) ISlocal declarationsBEGINexecute statementsEXCEPTIONexception handlers END name包(package)包其實(shí)就是被組合在一起的相關(guān)對(duì)象的集合,當(dāng)包中任何函數(shù)或存儲(chǔ)過(guò)程被調(diào)用,包就被加載入內(nèi)存中,包中的任何函數(shù)或存儲(chǔ)過(guò)程的子程序訪問(wèn)速度將大大加快。包由兩個(gè)部分組成:規(guī)范和包主體(body),規(guī)范描述變量、常量、游標(biāo)、和子程序,包體完全定義子程序和游標(biāo)。觸發(fā)器(trigger)觸發(fā)器與一個(gè)表或數(shù)據(jù)庫(kù)事件聯(lián)系在一起的,當(dāng)一個(gè)觸發(fā)器事件發(fā)生時(shí),定義在表上的觸發(fā)器被觸發(fā)。變量和常量變量存放在內(nèi)存中以獲得值,能被PL/SQL塊引用。你可以把變量想象成一個(gè)可儲(chǔ)藏東西的容器,容器內(nèi)的東西是可以改變的。聲明變量變量一般都在PL/SQL塊的聲明部分聲明,PL/SQL是一種強(qiáng)壯的類型語(yǔ)言,這就是說(shuō)在引用變量前必須首先聲明,要在執(zhí)行或異常處理部分使用變量,那么變量必須首先在聲明部分進(jìn)行聲明。聲明變量的語(yǔ)法如下:Variable_name CONSTANT databyte NOT NULL:=|DEFAULT expression注意:可以在聲明變量的同時(shí)給變量強(qiáng)制性的加上NOT NULL約束條件,此時(shí)變量在初始化時(shí)必須賦值。給變量賦值給變量賦值有兩種方式:. 直接給變量賦值X:=200;Y=Y+(X*20);. 通過(guò)SQL SELECT INTO 或FETCH INTO給變量賦值SELECT SUM(SALARY),SUM(SALARY*0.1)INTO TOTAL_SALARY,TATAL_COMMISSIONFROM EMPLOYEEWHERE DEPT=10;常量常量與變量相似,但常量的值在程序內(nèi)部不能改變,常量的值在定義時(shí)賦予,他的聲明方式與變量相似,但必須包括關(guān)鍵字CONSTANT。常量和變量都可被定義為SQL和用戶定義的數(shù)據(jù)類型。ZERO_VALUE CONSTANT NUMBER:=0;這個(gè)語(yǔ)句定了一個(gè)名叫ZERO_VALUE、數(shù)據(jù)類型是NUMBER、值為0的常量。標(biāo)量(scalar)數(shù)據(jù)類型標(biāo)量(scalar)數(shù)據(jù)類型沒(méi)有內(nèi)部組件,他們大致可分為以下四類:. number. character. date/time. boolean表1顯示了數(shù)字?jǐn)?shù)據(jù)類型;表2顯示了字符數(shù)據(jù)類型;表3顯示了日期和布爾數(shù)據(jù)類型。表1 Scalar Types:NumericDatatypeRangeSubtypesdescriptionBINARY_INTEGER-214748-2147483647NATURALNATURALNPOSITIVEPOSITIVENSIGNTYPE 用于存儲(chǔ)單字節(jié)整數(shù)。要求存儲(chǔ)長(zhǎng)度低于NUMBER值。用于限制范圍的子類型(SUBTYPE):NATURAL:用于非負(fù)數(shù)POSITIVE:只用于正數(shù)NATURALN:只用于非負(fù)數(shù)和非NULL值POSITIVEN:只用于正數(shù),不能用于NULL值SIGNTYPE:只有值:-1、0或1.NUMBER1.0E-130-9.99E125DECDECIMALDOUBLE PRECISIONFLOAT INTEGERICINTNUMERICREALSMALLINT存儲(chǔ)數(shù)字值,包括整數(shù)和浮點(diǎn)數(shù)??梢赃x擇精度和刻度方式,語(yǔ)法:number(,)。缺省的精度是38,scale是0.PLS_INTEGER-2147483647-2147483647與BINARY_INTEGER基本相同,但采用機(jī)器運(yùn)算時(shí),PLS_INTEGER提供更好的性能 。表2 字符數(shù)據(jù)類型 datatyperangsubtypedescriptionCHAR最大長(zhǎng)度32767字節(jié) CHARACTER存儲(chǔ)定長(zhǎng)字符串,如果長(zhǎng)度沒(méi)有確定,缺省是1LONG最大長(zhǎng)度2147483647字節(jié)存儲(chǔ)可變長(zhǎng)度字符串RAW 最大長(zhǎng)度32767字節(jié)用于存儲(chǔ)二進(jìn)制數(shù)據(jù)和字節(jié)字符串,當(dāng)在兩個(gè)數(shù)據(jù)庫(kù)之間進(jìn)行傳遞時(shí),RAW數(shù)據(jù)不在字符集之間進(jìn)行轉(zhuǎn)換。LONGRAW最大長(zhǎng)度2147483647與LONG數(shù)據(jù)類型相似,同樣他也不能在字符集之間進(jìn)行轉(zhuǎn)換。ROWID18個(gè)字節(jié)與數(shù)據(jù)庫(kù)ROWID偽列類型相同,能夠存儲(chǔ)一個(gè)行標(biāo)示符,可以將行標(biāo)示符看作數(shù)據(jù)庫(kù)中每一行的唯一鍵值。VARCHAR2最大長(zhǎng)度32767字節(jié)STRINGVARCHAR與VARCHAR數(shù)據(jù)類型相似,存儲(chǔ)可變長(zhǎng)度的字符串。聲明方法與VARCHAR相同 表3 DATE和BOOLEANdatatyperange descriptionBOOLEANTRUE/FALSE存儲(chǔ)邏輯值TRUE或FALSE,無(wú)參數(shù)DATE01/01/4712 BC 存儲(chǔ)固定長(zhǎng)的日期和時(shí)間值,日期值中包含時(shí)間LOB數(shù)據(jù)類型LOB(大對(duì)象,Large object) 數(shù)據(jù)類型用于存儲(chǔ)類似圖像,聲音這樣的大型數(shù)據(jù)對(duì)象,LOB數(shù)據(jù)對(duì)象可以是二進(jìn)制數(shù)據(jù)也可以是字符數(shù)據(jù),其最大長(zhǎng)度不超過(guò)4G。LOB數(shù)據(jù)類型支持任意訪問(wèn)方式,LONG只支持順序訪問(wèn)方式。LOB存儲(chǔ)在一個(gè)單獨(dú)的位置上,同時(shí)一個(gè)LOB定位符(LOB locator)存儲(chǔ)在原始的表中,該定位符是一個(gè)指向?qū)嶋H數(shù)據(jù)的指針。在PL/SQL中操作LOB數(shù)據(jù)對(duì)象使用ORACLE提供的包DBMS_LOB.LOB數(shù)據(jù)類型可分為以下四類:. BFILE. BLOB. CLOB. NCLOB操作符與其他程序設(shè)計(jì)語(yǔ)言相同,PL/SQL有一系列操作符。操作符分為下面幾類:. 算術(shù)操作符. 關(guān)系操作符. 比較操作符. 邏輯操作符算術(shù)操作符如表4所示operatoroperation+ 加- 減/ 除* 乘*乘方關(guān)系操作符主要用于條件判斷語(yǔ)句或用于where子串中,關(guān)系操作符檢查條件和結(jié)果是否為true或false,表5是PL/SQL中的關(guān)系操作符operatoroperation 小于操作符 大于操作符=大于或等于操作符= 等于操作符 != 不等于操作符 不等于操作符:= 賦值操作符表6 顯示的是比較操作符operator operationIS NULL如果操作數(shù)為NULL返回TRUELIKE比較字符串值BETWEEN驗(yàn)證值是否在范圍之內(nèi)IN驗(yàn)證操作數(shù)在設(shè)定的一系列值中表7.8顯示的是邏輯操作符operatoroperationAND 兩個(gè)條件都必須滿足OR只要滿足兩個(gè)條件中的一個(gè)NOT取反執(zhí)行部分執(zhí)行部分包含了所有的語(yǔ)句和表達(dá)式,執(zhí)行部分以關(guān)鍵字BEGIN開(kāi)始,以關(guān)鍵字EXCEPTION結(jié)束,如果EXCEPTION不存在,那么將以關(guān)鍵字END結(jié)束。分號(hào)分隔每一條語(yǔ)句,使用賦值操作符:=或SELECT INTO或FETCH INTO給每個(gè)變量賦值,執(zhí)行部分的錯(cuò)誤將在異常處理部分解決,在執(zhí)行部分中可以使用另一個(gè)PL/SQL程序塊,這種程序塊被稱為嵌套塊所有的SQL數(shù)據(jù)操作語(yǔ)句都可以用于執(zhí)行部分,PL/SQL塊不能再屏幕上顯示SELECT語(yǔ)句的輸出。SELECT語(yǔ)句必須包括一個(gè)INTO子串或者是游標(biāo)的一部分,執(zhí)行部分使用的變量和常量必須首先在聲明部分聲明,執(zhí)行部分必須至少包括一條可執(zhí)行語(yǔ)句,NULL是一條合法的可執(zhí)行語(yǔ)句,事物控制語(yǔ)句COMMIT和ROLLBACK可以在執(zhí)行部分使用,數(shù)據(jù)定義語(yǔ)言(Data Definition language)不能在執(zhí)行部分中使用,DDL語(yǔ)句與EXECUTE IMMEDIATE一起使用或者是DBMS_SQL調(diào)用。執(zhí)行一個(gè)PL/SQL塊SQL*PLUS中匿名的PL/SQL塊的執(zhí)行是在PL/SQL塊后輸入/來(lái)執(zhí)行,如下面的例子所示:declare v_comm_percent constant number:=10;beginupdate empset comm=sal*v_comm_percentwhere deptno=10;endSQL /PL/SQL procedure successfully completed.SQL命名的程序與匿名程序的執(zhí)行不同,執(zhí)行命名的程序塊必須使用execute關(guān)鍵字:create or replace procedure update_commission(v_dept in number,v_pervent in number default 10) is beginupdate empset comm=sal*v_percentwhere deptno=v_dept;endSQL/Procedure createdSQLexecute update_commission(10,15);PL/SQL procedure successfully completed.SQL 如果在另一個(gè)命名程序塊或匿名程序塊中執(zhí)行這個(gè)程序,那么就不需要EXECUTE關(guān)進(jìn)字。declarev_dept number;beginselect a.deptnointo v_deptfrom emp awhere job=PRESIDENTupdate_commission(v_dept);endSQL/PL/SQL procedure successfully completedSQL控制結(jié)構(gòu)控制結(jié)構(gòu)控制PL/SQL程序流程的代碼行,PL/SQL支持條件控制和循環(huán)控制結(jié)構(gòu)。語(yǔ)法和用途IF.THEN語(yǔ)法:IF condition THENStatements 1;Statements 2;.END IF IF語(yǔ)句判斷條件condition是否為TRUE,如果是,則執(zhí)行THEN后面的語(yǔ)句,如果condition為false或NULL則跳過(guò)THEN到END IF之間的語(yǔ)句,執(zhí)行END IF后面的語(yǔ)句。IF.THEN.ELSE語(yǔ)法:IF condition THENStatements 1;Statements 2;.ELSEStatements 1;Statements 2;.END IF 如果條件condition為TRUE,則執(zhí)行THEN到ELSE之間的語(yǔ)句,否則執(zhí)行ELSE到END IF之間的語(yǔ)句。IF 可以嵌套,可以在IF 或IF .ELSE語(yǔ)句中使用IF或IF.ELSE語(yǔ)句。if (ab) and (ac) theng:=a;elseg:=b;if cg theng:=c;end ifend ifIF.THEN.ELSIF語(yǔ)法:IF condition1 THENstatement1;ELSIF condition2 THENstatement2;ELSIF condition3 THENstatement3;ELSEstatement4;END IF;statement5;如果條件condition1為TRUE則執(zhí)行statement1,然后執(zhí)行statement5,否則判斷condition2是否為TRUE,若為TRUE則執(zhí)行statement2,然后執(zhí)行statement5,對(duì)于condition3也是相同的,如果condition1,condition2,condition3都不成立,那么將執(zhí)行statement4,然后執(zhí)行statement5。循環(huán)控制循環(huán)控制的基本形式是LOOP語(yǔ)句,LOOP和END LOOP之間的語(yǔ)句將無(wú)限次的執(zhí)行。LOOP語(yǔ)句的語(yǔ)法如下:LOOP statements;END LOOPLOOP和END LOOP之間的語(yǔ)句無(wú)限次的執(zhí)行顯然是不行的,那么在使用LOOP語(yǔ)句時(shí)必須使用EXIT語(yǔ)句,強(qiáng)制循環(huán)結(jié)束,例如:X:=100;LOOPX:=X+10;IF X1000 THENEXIT;END IFEND LOOP;Y:=X;此時(shí)Y的值是1010.EXIT WHEN語(yǔ)句將結(jié)束循環(huán),如果條件為TRUE,則結(jié)束循環(huán)。X:=100;LOOPX:=X+10;EXIT WHEN X1000;X:=X+10;END LOOP;Y:=X;WHILE.LOOPWHILE.LOOP有一個(gè)條件與循環(huán)相聯(lián)系,如果條件為TRUE,則執(zhí)行循環(huán)體內(nèi)的語(yǔ)句,如果結(jié)果為FALSE,則結(jié)束循環(huán)。X:=100;WHILE X=1000 LOOPX:=X+10;END LOOP;Y=X; FOR.LOOP語(yǔ)法:FOR counter IN REVERSE start_range.end_range LOOPstatements;END LOOP;LOOP和WHILE循環(huán)的循環(huán)次數(shù)都是不確定的,F(xiàn)OR循環(huán)的循環(huán)次數(shù)是固定的,counter是一個(gè)隱式聲明的變量,他的初始值是start_range,第二個(gè)值是start_range+1,直到end_range,如果start_range等于end _range,那么循環(huán)將執(zhí)行一次。如果使用了REVERSE關(guān)鍵字,那么范圍將是一個(gè)降序。X:=100;FOR v_counter in 1.10 loopx:=x+10;end loopy:=x;如果要退出for循環(huán)可以使用EXIT語(yǔ)句。標(biāo)簽用戶可以使用標(biāo)簽使程序獲得更好的可讀性。程序塊或循環(huán)都可以被標(biāo)記。標(biāo)簽的形式是。標(biāo)記程序塊DECLARE. . .BEGIN.EXCEPTION.END label_name標(biāo)記循環(huán)LOOP.loop.loop.EXIT outer_loop WHEN v_condition=0;end loop innermost_loop;.END LOOP inner_loop;END LOOP outer_loop; GOTO語(yǔ)句語(yǔ)法:GOTO LABEL;執(zhí)行GOTO語(yǔ)句時(shí),控制會(huì)立即轉(zhuǎn)到由標(biāo)簽標(biāo)記的語(yǔ)句。PL/SQL中對(duì)GOTO語(yǔ)句有一些限制,對(duì)于塊、循環(huán)、IF語(yǔ)句而言,從外層跳轉(zhuǎn)到內(nèi)層是非法的。X :=100;FOR V_COUNTER IN 1.10 LOOPIF V_COUNTER =4 THENGOTO end_of_loopEND IFX:=X+10;NULLEND LOOPY:=X; 注意:NULL是一個(gè)合法的可執(zhí)行語(yǔ)句。嵌套程序塊的內(nèi)部可以有另一個(gè)程序塊這種情況稱為嵌套。嵌套要注意的是變量,定義在最外部程序塊中的變量可以在所有子塊中使用,如果在子塊中定義了與外部程序塊變量相同的變量名,在執(zhí)行子塊時(shí)將使用子塊中定義的變量。子塊中定義的變量不能被父塊引用。同樣GOTO語(yǔ)句不能由父塊跳轉(zhuǎn)道子塊中,反之則是合法的。OUTER BLOCKDECLAREA_NUMBER INTEGER;B_NUMBER INTEGER;BEGIN-A_NUMBER and B_NUMBER are available hereDECLAREC_NUMBER INTEGERB_NUMBER NUMBER(20)BEGINC_NUMBER:=A_NUMBER;C_NUMBER=OUTER_BLOCK.B_NUMBER;END SUB_BLOCK;END OUT_BLOCK;小結(jié) 我們?cè)谶@篇文章中介紹了PL/SQL的基礎(chǔ)語(yǔ)法以及如何使用PL/SQL語(yǔ)言設(shè)計(jì)和運(yùn)行PL/SQL程序塊,并將PL/SQL程序整合到Oracle服務(wù)器中,雖然PL/SQL程序作為功能塊嵌入Oracle數(shù)據(jù)庫(kù)中,但PL/SQL與ORACLE數(shù)據(jù)庫(kù)的緊密結(jié)合使得越來(lái)越多的Oracle數(shù)據(jù)庫(kù)管理員和開(kāi)發(fā)人員開(kāi)始使用PL/SQL。全面探討PL/SQL的復(fù)合數(shù)據(jù)類型PL/SQL有兩種復(fù)合數(shù)據(jù)結(jié)構(gòu):記錄和集合。記錄由不同的域組成,集合由不同的元素組成。在本文中我們將討論記錄和集合的類型、怎樣定義和使用記錄和集合。PL/SQL 記錄記錄是PL/SQL的一種復(fù)合數(shù)據(jù)結(jié)構(gòu),scalar數(shù)據(jù)類型和其他數(shù)據(jù)類型只是簡(jiǎn)單的在包一級(jí)進(jìn)行預(yù)定義,但復(fù)合數(shù)據(jù)類型在使用前必須被定義,記錄之所以被稱為復(fù)合數(shù)據(jù)類型是因?yàn)樗捎蜻@種由數(shù)據(jù)元素的邏輯組所組成。域可以是scalar數(shù)據(jù)類型或其他記錄類型,它與c語(yǔ)言中的結(jié)構(gòu)相似,記錄也可以看成表中的數(shù)據(jù)行,域則相當(dāng)于表中的列,在表和虛擬表(視圖或查詢)中非常容易定義和使用,行或記錄中的每一列或域都可以被引用或單獨(dú)賦值,也可以通過(guò)一個(gè)單獨(dú)的語(yǔ)句引用記錄所有的域。在存儲(chǔ)過(guò)程或函數(shù)中記錄也可能有參數(shù)。創(chuàng)建記錄在PL/SQL中有兩種定義方式:顯式定義和隱式定義。一旦記錄被定義后,聲明或創(chuàng)建定義類型的記錄變量,然后才是使用該變量。隱式聲明是在基于表的結(jié)構(gòu)或查詢上使用%TYPE屬性,隱式聲明是一個(gè)更強(qiáng)有力的工具,這是因?yàn)檫@種數(shù)據(jù)變量是動(dòng)態(tài)創(chuàng)建的。顯式定義記錄顯式定義記錄是在PL/SQL程序塊中創(chuàng)建記錄變量之前在聲明部分定義。使用type命令定義記錄,然后在創(chuàng)建該記錄的變量。語(yǔ)法如下: TYPE record_type IS RECORD (field_definition_list);field_definition_list是由逗號(hào)分隔的列表。域定義的語(yǔ)法如下:field_name data_type_and_size NOT NULL:=|DEFAULT default_value域名必須服從與表或列的命名規(guī)則相同的命名規(guī)則。下面我們看一個(gè)例子:DELCARETYPE stock_quote_rec IS RECORD(symbol stock.symbol%TYPE,bid NUMBER(10,4),ask NUMBER(10,4),volume NUMBER NOT NULL:=0,exchange VARCHAR2(6) DEFAULT NASDAQ);real_time_quote stock_quote_rec;variable域定義時(shí)的%TYPE屬性用于引用數(shù)據(jù)庫(kù)中的表或視圖的數(shù)據(jù)類型和大小,而在此之前程序不知道類型和大小。在上面的例子中記錄域在編譯時(shí)將被定義為與列SYMBOL相同的數(shù)據(jù)類型和大小,當(dāng)代碼中要使用來(lái)自數(shù)據(jù)庫(kù)中的數(shù)據(jù)時(shí),在變量或域定義中最好使用%TYPE來(lái)定義。隱式定義記錄隱式定義記錄中,我們不用描述記錄的每一個(gè)域。這是因?yàn)槲覀儾恍枰x記錄的結(jié)構(gòu),不需要使用TYPE語(yǔ)句,相反在聲明記錄變量時(shí)使用%ROWTYPE命令定義與數(shù)據(jù)庫(kù)表,視圖,游標(biāo)有相同結(jié)構(gòu)的記錄,與TYPE命令相同的是它是一種定義獲得數(shù)據(jù)庫(kù)數(shù)據(jù)記錄的好方法。DECLAREaccounter_info accounts%ROWTYPR;CURSOR xactions_cur(acct_no IN VARCHAR2) ISSELECT action,timestamp,holdingFROM portfoliosWHERE account_nbr=acct_no;xaction_info xactions_cur%ROWTYPE;variable有一些PL/SQL指令在使用隱式定義記錄時(shí)沒(méi)有使用%ROWTYPE屬性,比如游標(biāo)FOR循環(huán)或觸發(fā)器中的:old和:new記錄。DELCARECURSOR xaction_cur ISSELECT action,timeamp,holdingFROM portfoliosWHERE account_nbr=37;BEGINFOR xaction_rec in xactions_curLOOPIF xactions_rec.holding=ORCLTHENnotify_shareholder;END IF;END LOOP;使用記錄用戶可以給記錄賦值、將值傳遞給其他程序。記錄作為一種復(fù)合數(shù)據(jù)結(jié)構(gòu)意味作他有兩個(gè)層次可用。用戶可以引用整個(gè)記錄,使用select into或fetch轉(zhuǎn)移所有域,也可以將整個(gè)記錄傳遞給一個(gè)程序或?qū)⑺杏虻闹蒂x給另一個(gè)記錄。在更低的層次,用戶可以處理記錄內(nèi)單獨(dú)的域,用戶可以給單獨(dú)的域賦值或者在單獨(dú)的域上運(yùn)行布爾表達(dá)式,也可以將一個(gè)或更多的域傳遞給另一個(gè)程序。引用記錄記錄由域組成,訪問(wèn)記錄中的域使用點(diǎn)(.)符號(hào)。我們使用上面的例子看看DELCARETYPE stock_quote_rec IS RECORD(symbol stock.symbol%TYPE,bid NUMBER(10,4),ask NUMBER(10,4),volume NUMBER NOT NULL:=0,exchange VARCHAR2(6) DEFAULT NASDAQ);TYPE detailed_quote_rec IS RECORD(quote stock_quote_rec,timestamp date,bid_size NUMBER,ask.size NUMBER,last_tick VARCHAR2(4);real_time_detail detail_quote_rec;BEGINreal_time_detail.bid_size:=1000;real_time_detail.quote.volume:=156700;log_quote(real_time_detail.quote);給記錄賦值給記錄或記錄中的域賦值的方法有幾種,可以使用SELECT INTO或FETCH給整個(gè)記錄或單獨(dú)的域賦值, 可以將整個(gè)記錄的值賦給其他記錄,也可以通過(guò)給每個(gè)域賦值來(lái)得到記錄,以下我們通過(guò)實(shí)例講解每一種賦值方法。1、使用SELECT INTO使用SELECT INTO給記錄賦值要將記錄或域放在INTO子串中,INTO子串中的變量與SELECT中列的位置相對(duì)應(yīng)。例:DECLAREstock_info1 stocks%ROWTYPE;stock_info2 stocks%ROWTYPE;BEGINSELECT symbol,exchangeINTO stock_info1.symbol,stock_info1.exchangeFROM stocksWHERE symbol=ORCL;SELECT * INTO stock_info2 FROM stocksWHERE symbol=ORCL;2、使用FETCH如果SQL語(yǔ)句返回多行數(shù)據(jù)或者希望使用帶參數(shù)的游標(biāo),那么就要使用游標(biāo),這種情況下使用FETCH語(yǔ)句代替INSTEAD INTO是一個(gè)更簡(jiǎn)單、更有效率的方法,但在安全性較高的包中FETCH的語(yǔ)法如下:FETCH cursor_name INTO variable;我們改寫(xiě)上面的例子:DECLARECURSOR stock_cur(symbol_in VARCHAR2) IS SELECT symbol,exchange,begin_dateFROM stockWHERE symbol=UPPER(symbol_in);stock_info stock_cur%ROWTYPEBEGINOPEN stock_cur(ORCL);FETCH stock_cur INTO stock_info;使用賦值語(yǔ)句將整個(gè)記錄復(fù)制給另一個(gè)記錄是一項(xiàng)非常有用的技術(shù),不過(guò)記錄必須精確地被聲明為相同的類型,不能是基于兩個(gè)不同的TYPE語(yǔ)句來(lái)獲得相同的結(jié)構(gòu)。例:DECLARETYPE stock_quote_rec IS RECORD(symbol stocks.symbol%TYPE,bid NUMBER(10,4),ask number(10,4),volume NUMBER);TYPE stock_quote_too IS RECORD(symbol stocks.symbol%TYPE,bid NUMBER(10,4),ask number(10,4),volume NUMBER);-這兩個(gè)記錄看上去是一樣的,但實(shí)際上是不一樣的stock_one stocks_quote_rec;stock_two stocks_quote_rec; -這兩個(gè)域有相同的數(shù)據(jù)類型和大小stock_also stock_rec_too;-與stock_quote_rec是不同的數(shù)據(jù)類型 BEGINstock_one.symbol:=orcl;stock_one.volume:=1234500;stock_two:=stock_one;-正確syock_also:=stock_one;-錯(cuò)誤,數(shù)據(jù)類型錯(cuò)誤stock_also.symbol:=stock_one.symbol;stock_also.volume:=stock_one.volume; 記錄不能用于INSERT語(yǔ)句和將記錄直接用于比較,下面兩種情況是錯(cuò)誤的:INSERT INTO stocks VALUES (stock_record);和IF stock_rec1stock_rec2 THEN要特別注意考試中試題中有可能用%ROWTYPE來(lái)欺騙你,但這是錯(cuò)誤的,記住這一點(diǎn)。還有可能會(huì)出現(xiàn)用記錄排序的情況,ORACLE不支持記錄之間的直接比較。對(duì)于記錄比較,可以采用下面的兩個(gè)選擇:. 設(shè)計(jì)一個(gè)函數(shù),該函數(shù)返回scalar數(shù)據(jù)類型,使用這個(gè)函數(shù)比較記錄,如IF sort_rec(stock_one)sort_rec(stock_two) THEN. 可以使用數(shù)據(jù)庫(kù)對(duì)象,數(shù)據(jù)庫(kù)對(duì)象可以使用order或map方法定義,允許oracle對(duì)復(fù)合數(shù)據(jù)類型進(jìn)行比較。關(guān)于數(shù)據(jù)庫(kù)對(duì)象的討論已經(jīng)超越了本文的范圍,要詳細(xì)了解數(shù)據(jù)庫(kù)對(duì)象,可以查閱oracle手冊(cè)。PL/SQL集合集合與其他語(yǔ)言中的數(shù)組相似,在ORACLE7.3及以前的版本中只有一種集合稱為PL/SQL表,這種類型的集合依然保留,就是索引(INDEX_BY)表,與記錄相似,集合在定義的時(shí)候必須使用TYPE語(yǔ)句,然后才是創(chuàng)建和使用這種類型的變量。集合的類型PL/SQL有三種類型的集合. Index_by表. 嵌套表. VARRAY這三種類型的集合之間由許多差異,包括數(shù)據(jù)綁定、稀疏性(sparsity)、數(shù)據(jù)庫(kù)中的存儲(chǔ)能力都不相同。綁定涉及到集合中元素?cái)?shù)量的限制,VARRAY集合中的元素的數(shù)量是有限,Index_by和嵌套表則是沒(méi)有限制的。稀疏性描述了集合的下標(biāo)是否有間隔,Index_by表總是稀疏的,如果元素被刪除了嵌套表可以是稀疏的,但VARRAY類型的集合則是緊密的,它的下標(biāo)之間沒(méi)有間隔。Index_by表不能存儲(chǔ)在數(shù)據(jù)庫(kù)中,但嵌套表和VARRAY可以被存儲(chǔ)在數(shù)據(jù)庫(kù)中。雖然這三種類型的集合有很多不同之處,但他們也由很多相似的地方:. 都是一維的類似數(shù)組的結(jié)構(gòu). 都有內(nèi)建的方法. 訪問(wèn)由點(diǎn)分隔Index_by表Index_by表集合的定義語(yǔ)法如下:TYPE type_name IS TABLE OF element_type NOT NULL INDEXBY BINARY_INTERGET;這里面重要的關(guān)鍵字是INDEX BY BINARY_INTERGET,沒(méi)有這個(gè)關(guān)鍵字,那么集合將是一個(gè)嵌套表,element_type可以是任何合法的PL/SQL數(shù)據(jù)類型,包括:PLS/INTEGER、SIGNTYPE、和BOOLEAN。其他的集合類型對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)類型都有限制,但I(xiàn)ndex_by表不能存儲(chǔ)在數(shù)據(jù)庫(kù)中,所以沒(méi)有這些限制。一旦定義了index_by表,就可以向創(chuàng)建其他變量那樣創(chuàng)建index_by表的變量:DECLARE TYPE symbol_tab_typ IS TABLE OF VARCHAR2(5) INDEX BY BINARY_INTEGER;symbol_tab symbol_tab_typ;BEGIN嵌套表嵌套表非常類似于Index_by表,創(chuàng)建的語(yǔ)法也非常相似。使用TYPE語(yǔ)句,只是沒(méi)有INDEX BY BINARY_INTEGER子串。TYPE type_name IS TABLE OF element_type NOT NULLNOT NULL選項(xiàng)要求集合所有的元素都要有值,element_type可以是一個(gè)記錄,但是這個(gè)記錄只能使用標(biāo)量數(shù)據(jù)類型字段以及只用于數(shù)據(jù)庫(kù)的數(shù)據(jù)類型(不能是PLS_INTEGER,BOOLEAN或SIGNTYPE)。嵌套表和VARRAY都能作為列存儲(chǔ)在數(shù)據(jù)庫(kù)表中,所以集合自身而不是單個(gè)的元素可以為NULL,ORACLE稱這種整個(gè)集合為NULL的為自動(dòng)設(shè)置為NULL(atomically NULL)以區(qū)別元素為NULL的情況。當(dāng)集合為NULL時(shí),即使不會(huì)產(chǎn)生異常,用戶也不能引用集合中的元素。用戶可以使用IS NULL操作符檢測(cè)集合是否為NULL。存儲(chǔ)在一個(gè)數(shù)據(jù)庫(kù)中的嵌套表并不與表中的其它數(shù)據(jù)存放在同一個(gè)數(shù)據(jù)塊中,它們實(shí)際上被存放在第二個(gè)表中。正如沒(méi)有order by子句select語(yǔ)句不能保證返回任何有順序的數(shù)據(jù),從數(shù)據(jù)庫(kù)中取回的嵌套表也不保證元素的順序。由于集合數(shù)據(jù)是離線存儲(chǔ)的,對(duì)于大型集合嵌套表是一個(gè)不錯(cuò)的選擇。VARRAYVARRAY或數(shù)據(jù)變量都有元素的限制。想起他集合一樣VARRAY定義仍然使用TYPE語(yǔ)句,但關(guān)鍵字VARRAY或VARRYING ARRAY告訴ORACLE這是一個(gè)VARRAY集合。TYPE type_name IS VARRAY|VARYING ARRAY (max_size) OFelement_type NOT NULLmax_size是一個(gè)整數(shù),用于標(biāo)示VARRAY集合擁有的最多元素?cái)?shù)目。VARRAY集合的元素?cái)?shù)量可以低于max_size,但不能超過(guò)max_size。element_type是一維元素的數(shù)據(jù)類型,如果element_type是記錄,那么這個(gè)記錄只能使用標(biāo)量數(shù)據(jù)字段(與嵌套標(biāo)相似)。NOT NULL子串表示集合中的每一個(gè)元素都必須有值。與嵌套表相似,VARRAY能夠自動(dòng)為NULL,可以使用IS NULL操作符進(jìn)行檢測(cè)。與嵌套表不同的是,當(dāng)VARRAY存儲(chǔ)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(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)論