PL/SQL光標(biāo)為程序提供了從數(shù)據(jù)庫(kù)中選擇多行數(shù)據(jù),然后對(duì)每行數(shù)據(jù)單獨(dú)進(jìn)行處理的方法,它為Oracle提供了一種指示和控制SQL處理的各個(gè)階段的方法。我將認(rèn)為您已經(jīng)對(duì)PL/SQL有一定的了解。通過(guò)本文,您將學(xué)會(huì):
光標(biāo)的創(chuàng)建
光標(biāo)的處理
定義和使用光標(biāo)屬性
一、 什么是光標(biāo)
Oracle使用兩種光標(biāo):顯式光標(biāo)和隱式光標(biāo)。不管語(yǔ)句返回多少條紀(jì)錄,PL/SQL為使用的每一條UPDATE、DELETE和INSERT等SQL命令隱式的聲明一個(gè)光標(biāo)。(要管理SQL語(yǔ)句的處理,必須隱式的給它定義一個(gè)光標(biāo)。)用戶(hù)聲明并使用顯示光標(biāo)處理SELECT語(yǔ)句返回的多條記錄。顯示的定義光標(biāo)一種結(jié)構(gòu),它使用戶(hù)能夠?yàn)樘囟ǖ恼Z(yǔ)句指定內(nèi)存區(qū)域,以便以后使用。
二、 光標(biāo)的作用
當(dāng)PL/SQL光標(biāo)查詢(xún)返回多行數(shù)據(jù)時(shí),這些記錄組被稱(chēng)為活動(dòng)集。Oracle將這種活動(dòng)集存儲(chǔ)在您創(chuàng)建的顯示定義的已命名的光標(biāo)中。Oracle光標(biāo)是一種用于輕松的處理多行數(shù)據(jù)的機(jī)制,沒(méi)有光標(biāo),Oracle開(kāi)發(fā)人員必須單獨(dú)地、顯式地取回并管理光標(biāo)查詢(xún)選擇的每一條記錄。
光標(biāo)的另一項(xiàng)功能事,它包含一個(gè)跟蹤當(dāng)前訪問(wèn)的記錄的指針,這使您的程序能夠一次處理多條記錄。
三、 使用顯示光標(biāo)的基本方法
步驟如下:
聲明光標(biāo)
打開(kāi)光標(biāo)
從光標(biāo)中取回?cái)?shù)據(jù)
關(guān)閉光標(biāo)
1、聲明光標(biāo)
聲明光標(biāo)的語(yǔ)法如下:
DECLARE cursor_name
Is
SELECT statement
其中,cursor_name是您給光標(biāo)指定的名稱(chēng);SELECT statement是給光標(biāo)活動(dòng)集返回記錄的查詢(xún)。
聲明光標(biāo)完成了下面兩個(gè)目的:
給光標(biāo)命名;
將一個(gè)查詢(xún)與光標(biāo)關(guān)聯(lián)起來(lái)。
值得注意的是,必須在PL/SQL塊的聲明部分聲明光標(biāo);給光標(biāo)指定的名稱(chēng)是一個(gè)未聲明的標(biāo)識(shí)符,而不是一個(gè)PL/SQL變量,不能給光標(biāo)名稱(chēng)賦值,也不能將它用在表達(dá)式中。PL/SQL塊使用這個(gè)名稱(chēng)來(lái)引用光標(biāo)查詢(xún)。
例:DECLARE
CURSOR c1
Is
SELECT VIEW_NAME FROM ALL_VIEWS
WHERE ROWNUM<=10;
另外還可以在光標(biāo)定義語(yǔ)句中聲明光標(biāo)的參數(shù),例:
CURSOR c1(view _nbr number)
Is
SELECT VIEW_NAME FROM ALL_VIEWS
WHERE ROWNUM<= view _nbr;
光標(biāo)參數(shù)只對(duì)相應(yīng)的光標(biāo)是可見(jiàn)的,不能在光標(biāo)范圍之外引用該光標(biāo)的參數(shù)。如果試圖這樣做,Oracle將返回一個(gè)錯(cuò)誤,指出該變量沒(méi)有定義。
2、打開(kāi)光標(biāo)
打開(kāi)光標(biāo)的語(yǔ)法如下:
OPEN cursor_name;
其中cursor_name是您以前定義的光標(biāo)名稱(chēng)。
打開(kāi)光標(biāo)將激活查詢(xún)并識(shí)別活動(dòng)集,可是在執(zhí)行光標(biāo)取回命令之前,并沒(méi)有真正取回記錄。OPEN命令還初始化了光標(biāo)指針,使其指向活動(dòng)集的第一條記錄。光標(biāo)被打開(kāi)后,直到關(guān)閉之前,取回到活動(dòng)集的所有數(shù)據(jù)都是靜態(tài)的,換句話說(shuō),光標(biāo)忽略所有在光標(biāo)打開(kāi)之后,對(duì)數(shù)據(jù)執(zhí)行的SQL DML命令(INSERT、UPDATE、DELETE和SELECT)。因此只有在需要時(shí)才打開(kāi)它,要刷新活動(dòng)集,只需關(guān)閉并重新打開(kāi)光標(biāo)即可。
3、從光標(biāo)中取回?cái)?shù)據(jù)
FETCH命令以每次一條記錄的方式取回活動(dòng)集中的記錄。通常將FETCH命令和某種迭代處理結(jié)合起來(lái)使用,在迭代處理中,F(xiàn)ETCH命令每執(zhí)行一次,光標(biāo)前進(jìn)到活動(dòng)集的下一條記錄。
FETCH命令的語(yǔ)法:
FETCH cursor_name INTO record_list;
其中,cursor_name是前面定義的光標(biāo)的名稱(chēng);record_list是變量列表,它接受活動(dòng)集中的列。FETCH命令將活動(dòng)集的結(jié)果放置到這些變量中。
執(zhí)行FETCH命令后,活動(dòng)集中的結(jié)果被取回到PL/SQL變量中,以便在PL/SQL塊中使用。每取回一條記錄,光標(biāo)的指針就移向活動(dòng)集的下一條記錄。
例:
FETCH C1 INTO VNAME;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(C1%ROWCOUNT)||' '||VNAME);
END LOOP;
其中,使用屬性'%FOUND'使得當(dāng)FETCH到達(dá)活動(dòng)集的結(jié)尾時(shí),不會(huì)引發(fā)異常。其它屬性及含義見(jiàn)下表:
屬性 含量
%FOUND 布爾型屬性,當(dāng)最近一次該記錄時(shí)成功返回,則值為T(mén)RUE
%NOTFOUND 布爾型屬性,它的值總與%FOUND屬性的值相反
%ISOPEN 布爾型屬性,當(dāng)光標(biāo)是打開(kāi)時(shí)返回TRUE
%ROWCOUNT 數(shù)字型屬性,返回已從光標(biāo)中讀取的記錄數(shù)
屬性 含量
%FOUND 布爾型屬性,當(dāng)最近一次該記錄時(shí)成功返回,則值為T(mén)RUE
%NOTFOUND 布爾型屬性,它的值總與%FOUND屬性的值相反
%ISOPEN 布爾型屬性,當(dāng)光標(biāo)是打開(kāi)時(shí)返回TRUE
%ROWCOUNT 數(shù)字型屬性,返回已從光標(biāo)中讀取的記錄數(shù)
4、關(guān)閉光標(biāo)
CLOSE語(yǔ)句關(guān)閉以前打開(kāi)的光標(biāo),使得活動(dòng)集不確定。當(dāng)用戶(hù)的程序或會(huì)話結(jié)束時(shí),Oracle隱式關(guān)閉光標(biāo)。光標(biāo)被關(guān)閉后,就不能對(duì)它執(zhí)行任何操作了,否則將引發(fā)異常。
CLOSE語(yǔ)句的語(yǔ)法是:
CLOSE cursor_name;
其中,cursor_name是以前打開(kāi)的光標(biāo)的名稱(chēng)。
完整的程序代碼如下:
DECLARE
CURSOR C1 IS SELECT VIEW_NAME FROM ALL_VIEWS
WHERE ROWNUM<=10
ORDER BY VIEW_NAME;
VNAME VARCHAR2(40);
BEGIN
OPEN C1;
FETCH C1 INTO VNAME;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(C1%ROWCOUNT)||''||VNAME);
END LOOP;
END;
……CLOSE C1;
四、 小結(jié)
光標(biāo)是一種結(jié)構(gòu),能夠以一次一條記錄的方式處理多行查詢(xún)的結(jié)果.為每條DML語(yǔ)句創(chuàng)建隱式光標(biāo),而顯式光標(biāo)是由用戶(hù)創(chuàng)建的,以便處理返回多條記錄的查詢(xún)。而且,通過(guò)消除反復(fù)地分析代碼,光標(biāo)提高了代碼的處理速度。
光標(biāo)的創(chuàng)建
光標(biāo)的處理
定義和使用光標(biāo)屬性
一、 什么是光標(biāo)
Oracle使用兩種光標(biāo):顯式光標(biāo)和隱式光標(biāo)。不管語(yǔ)句返回多少條紀(jì)錄,PL/SQL為使用的每一條UPDATE、DELETE和INSERT等SQL命令隱式的聲明一個(gè)光標(biāo)。(要管理SQL語(yǔ)句的處理,必須隱式的給它定義一個(gè)光標(biāo)。)用戶(hù)聲明并使用顯示光標(biāo)處理SELECT語(yǔ)句返回的多條記錄。顯示的定義光標(biāo)一種結(jié)構(gòu),它使用戶(hù)能夠?yàn)樘囟ǖ恼Z(yǔ)句指定內(nèi)存區(qū)域,以便以后使用。
二、 光標(biāo)的作用
當(dāng)PL/SQL光標(biāo)查詢(xún)返回多行數(shù)據(jù)時(shí),這些記錄組被稱(chēng)為活動(dòng)集。Oracle將這種活動(dòng)集存儲(chǔ)在您創(chuàng)建的顯示定義的已命名的光標(biāo)中。Oracle光標(biāo)是一種用于輕松的處理多行數(shù)據(jù)的機(jī)制,沒(méi)有光標(biāo),Oracle開(kāi)發(fā)人員必須單獨(dú)地、顯式地取回并管理光標(biāo)查詢(xún)選擇的每一條記錄。
光標(biāo)的另一項(xiàng)功能事,它包含一個(gè)跟蹤當(dāng)前訪問(wèn)的記錄的指針,這使您的程序能夠一次處理多條記錄。
三、 使用顯示光標(biāo)的基本方法
步驟如下:
聲明光標(biāo)
打開(kāi)光標(biāo)
從光標(biāo)中取回?cái)?shù)據(jù)
關(guān)閉光標(biāo)
1、聲明光標(biāo)
聲明光標(biāo)的語(yǔ)法如下:
DECLARE cursor_name
Is
SELECT statement
其中,cursor_name是您給光標(biāo)指定的名稱(chēng);SELECT statement是給光標(biāo)活動(dòng)集返回記錄的查詢(xún)。
聲明光標(biāo)完成了下面兩個(gè)目的:
給光標(biāo)命名;
將一個(gè)查詢(xún)與光標(biāo)關(guān)聯(lián)起來(lái)。
值得注意的是,必須在PL/SQL塊的聲明部分聲明光標(biāo);給光標(biāo)指定的名稱(chēng)是一個(gè)未聲明的標(biāo)識(shí)符,而不是一個(gè)PL/SQL變量,不能給光標(biāo)名稱(chēng)賦值,也不能將它用在表達(dá)式中。PL/SQL塊使用這個(gè)名稱(chēng)來(lái)引用光標(biāo)查詢(xún)。
例:DECLARE
CURSOR c1
Is
SELECT VIEW_NAME FROM ALL_VIEWS
WHERE ROWNUM<=10;
另外還可以在光標(biāo)定義語(yǔ)句中聲明光標(biāo)的參數(shù),例:
CURSOR c1(view _nbr number)
Is
SELECT VIEW_NAME FROM ALL_VIEWS
WHERE ROWNUM<= view _nbr;
光標(biāo)參數(shù)只對(duì)相應(yīng)的光標(biāo)是可見(jiàn)的,不能在光標(biāo)范圍之外引用該光標(biāo)的參數(shù)。如果試圖這樣做,Oracle將返回一個(gè)錯(cuò)誤,指出該變量沒(méi)有定義。
2、打開(kāi)光標(biāo)
打開(kāi)光標(biāo)的語(yǔ)法如下:
OPEN cursor_name;
其中cursor_name是您以前定義的光標(biāo)名稱(chēng)。
打開(kāi)光標(biāo)將激活查詢(xún)并識(shí)別活動(dòng)集,可是在執(zhí)行光標(biāo)取回命令之前,并沒(méi)有真正取回記錄。OPEN命令還初始化了光標(biāo)指針,使其指向活動(dòng)集的第一條記錄。光標(biāo)被打開(kāi)后,直到關(guān)閉之前,取回到活動(dòng)集的所有數(shù)據(jù)都是靜態(tài)的,換句話說(shuō),光標(biāo)忽略所有在光標(biāo)打開(kāi)之后,對(duì)數(shù)據(jù)執(zhí)行的SQL DML命令(INSERT、UPDATE、DELETE和SELECT)。因此只有在需要時(shí)才打開(kāi)它,要刷新活動(dòng)集,只需關(guān)閉并重新打開(kāi)光標(biāo)即可。
3、從光標(biāo)中取回?cái)?shù)據(jù)
FETCH命令以每次一條記錄的方式取回活動(dòng)集中的記錄。通常將FETCH命令和某種迭代處理結(jié)合起來(lái)使用,在迭代處理中,F(xiàn)ETCH命令每執(zhí)行一次,光標(biāo)前進(jìn)到活動(dòng)集的下一條記錄。
FETCH命令的語(yǔ)法:
FETCH cursor_name INTO record_list;
其中,cursor_name是前面定義的光標(biāo)的名稱(chēng);record_list是變量列表,它接受活動(dòng)集中的列。FETCH命令將活動(dòng)集的結(jié)果放置到這些變量中。
執(zhí)行FETCH命令后,活動(dòng)集中的結(jié)果被取回到PL/SQL變量中,以便在PL/SQL塊中使用。每取回一條記錄,光標(biāo)的指針就移向活動(dòng)集的下一條記錄。
例:
FETCH C1 INTO VNAME;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(C1%ROWCOUNT)||' '||VNAME);
END LOOP;
其中,使用屬性'%FOUND'使得當(dāng)FETCH到達(dá)活動(dòng)集的結(jié)尾時(shí),不會(huì)引發(fā)異常。其它屬性及含義見(jiàn)下表:
屬性 含量
%FOUND 布爾型屬性,當(dāng)最近一次該記錄時(shí)成功返回,則值為T(mén)RUE
%NOTFOUND 布爾型屬性,它的值總與%FOUND屬性的值相反
%ISOPEN 布爾型屬性,當(dāng)光標(biāo)是打開(kāi)時(shí)返回TRUE
%ROWCOUNT 數(shù)字型屬性,返回已從光標(biāo)中讀取的記錄數(shù)
屬性 含量
%FOUND 布爾型屬性,當(dāng)最近一次該記錄時(shí)成功返回,則值為T(mén)RUE
%NOTFOUND 布爾型屬性,它的值總與%FOUND屬性的值相反
%ISOPEN 布爾型屬性,當(dāng)光標(biāo)是打開(kāi)時(shí)返回TRUE
%ROWCOUNT 數(shù)字型屬性,返回已從光標(biāo)中讀取的記錄數(shù)
4、關(guān)閉光標(biāo)
CLOSE語(yǔ)句關(guān)閉以前打開(kāi)的光標(biāo),使得活動(dòng)集不確定。當(dāng)用戶(hù)的程序或會(huì)話結(jié)束時(shí),Oracle隱式關(guān)閉光標(biāo)。光標(biāo)被關(guān)閉后,就不能對(duì)它執(zhí)行任何操作了,否則將引發(fā)異常。
CLOSE語(yǔ)句的語(yǔ)法是:
CLOSE cursor_name;
其中,cursor_name是以前打開(kāi)的光標(biāo)的名稱(chēng)。
完整的程序代碼如下:
DECLARE
CURSOR C1 IS SELECT VIEW_NAME FROM ALL_VIEWS
WHERE ROWNUM<=10
ORDER BY VIEW_NAME;
VNAME VARCHAR2(40);
BEGIN
OPEN C1;
FETCH C1 INTO VNAME;
WHILE C1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(C1%ROWCOUNT)||''||VNAME);
END LOOP;
END;
……CLOSE C1;
四、 小結(jié)
光標(biāo)是一種結(jié)構(gòu),能夠以一次一條記錄的方式處理多行查詢(xún)的結(jié)果.為每條DML語(yǔ)句創(chuàng)建隱式光標(biāo),而顯式光標(biāo)是由用戶(hù)創(chuàng)建的,以便處理返回多條記錄的查詢(xún)。而且,通過(guò)消除反復(fù)地分析代碼,光標(biāo)提高了代碼的處理速度。