Oracle數(shù)據(jù)庫中的循環(huán)語法及舉例
前言
在 Oracle 數(shù)據(jù)庫中,提供了多種循環(huán)類型用于實現(xiàn)不同的業(yè)務邏輯需求。我們可以使用 PL/SQL 中的循環(huán)語句來實現(xiàn)反復執(zhí)行一段代碼塊的目的。PL/SQL 是一種過程化語言,提供了完善的控制流結(jié)構(gòu),支持多種循環(huán)形式。下面介紹一些常用的循環(huán)語句及其語法和示例。
一、簡單循環(huán)
之所以會被叫做簡單循環(huán):因為它僅是以LOOP關鍵字開始,以END LOOP語句結(jié)束。要靠循環(huán)體內(nèi)的EXIT、EXIT WHEN或者RETURN來退出循環(huán)(或者有異常拋出)。這種循環(huán)為LOOP 循環(huán),是一種無限循環(huán),它會反復執(zhí)行一個語句塊,直到遇到 BREAK 語句為止。LOOP 循環(huán)在程序中也通常用于等待某個條件變?yōu)檎鏁r再退出循環(huán),或者在處理數(shù)據(jù)集合時用來查找某個特定的記錄。
1.1LOOP 循環(huán)語法:
LOOP 循環(huán)的語法如下:
LOOP
-- statements to be executed
EXIT [WHEN condition];
END LOOP;
--簡單理解為:
loop
要執(zhí)行的語句; ┐
exit when 退出條件; ├循環(huán)體
[要執(zhí)行的語句;] ┘
end loop;EXIT 是一個可選關鍵字,可以用來指定跳出循環(huán)的條件; condition 是一個布爾表達式,當其值為 TRUE 時會導致循環(huán)退出。
1.2LOOP 循環(huán)示例
下面就是使用 LOOP 循環(huán)的一些示例
示例1.循環(huán)打印1-10,代碼如下:
declare
v1 number:=0;
begin
loop
v1:=v1+1;
dbms_output.put_line(v1);
exit when v1=10;
end loop;
end;輸出結(jié)果如下:

示例2.循環(huán)打印1-10的和,代碼如下:
declare
v1 number:=1;--自增
v2 number:=0;--求和
begin
loop
v2:=v2+v1;
dbms_output.put_line(v2);
exit when v1=10;
v1:=v1+1;
end loop;
end;輸出結(jié)果如下:

示例3.只打印1-10的和,代碼如下:
declare
v1 number:=1;--自增
v2 number:=0;--求和
begin
loop
v2:=v2+v1;
exit when v1=10;
v1:=v1+1;
end loop;
dbms_output.put_line(v2);
end;輸出如下:

示例4. 不換行打印1-10,代碼如下:
declare
v1 number:=0;
begin
loop
v1:=v1+1;
dbms_output.put(v1||',');
exit when v1=10;
end loop;
dbms_output.put_line('');
end;輸出結(jié)果如下:

示例5.循環(huán)打印1+2+3+4...+10=55這個式子,代碼如下:
declare
v1 number:=1;--自增
v2 number:=0;--求和
begin
loop
v2:=v2+v1; --求和
dbms_output.put(v1||'+');
v1:=v1+1;--自增
exit when v1=10;--退出
end loop;
dbms_output.put_line(v1||'='||(v2+v1));
end;輸出結(jié)果如下:

示例6.讀取一張表中所有員工記錄,代碼如下:
DECLARE
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
v_job emp.job%TYPE;
v_mgr emp.mgr%TYPE;
v_hiredate emp.hiredate%TYPE;
v_sal emp.sal%TYPE;
v_comm emp.comm%TYPE;
v_deptno emp.deptno%TYPE;
CURSOR c_emp IS SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno
FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_empno, v_ename, v_job, v_mgr, v_hiredate, v_sal, v_comm, v_deptno;
EXIT WHEN c_emp%NOTFOUND;
-- 在這里可以對每個員工記錄進行處理,例如打印或者插入到另一個表中等操作
DBMS_OUTPUT.PUT_LINE('empno=' || v_empno || ', ename=' || v_ename || ', job=' || v_job || ', mgr=' || v_mgr || ', hiredate=' || v_hiredate || ', sal=' || v_sal || ', comm=' || v_comm || ', deptno=' || v_deptno);
END LOOP;
CLOSE c_emp;
END;上述代碼我創(chuàng)建了一個名為 c_emp 的游標,該游標從 emp 表中選擇所有員工記錄。要知道游標是會遍歷表所有行,然后我使用 LOOP 循環(huán)和 FETCH 語句來逐行讀取游標中的數(shù)據(jù),并將其存儲到變量中。在每次循環(huán)迭代時,我可以對每個員工記錄進行處理,例如打印或者插入到另一個表中等操作。最后,我再通過 CLOSE 語句關閉了游標。這里需要注意,使用游標時需要進行顯式地打開和關閉操作。下圖是輸出結(jié)果:

示例7.打印九九乘法表,代碼如下:
第一種格式對齊代碼如下:
begin
Dbms_Output.put_line('九九乘法表');
for i in 1..9 loop
for j in 1..i loop
dbms_output.put(j||'*'||i||'='|| lpad(i*j,2,0)||' ');
end loop;
dbms_output.put_line('');
end loop;
end;輸出結(jié)果如下:

第二種代碼如下:
declare
i int:=1;
j int:=1;
begin
loop
loop
Dbms_Output.put(i||'*'||j||'='||i*j);
dbms_output.put(' ');
j:=j+1;
exit when j>i;
end loop;
dbms_output.put_line('');
i:=i+1;
j:=1;
exit when i>9;
end loop;
end;輸出結(jié)果如下:

二、for循環(huán)
FOR 循環(huán)是一種最常見的循環(huán)形式,在固定范圍內(nèi)反復執(zhí)行某些操作,在程序中通常用于遍歷一個數(shù)據(jù)集合或執(zhí)行指定次數(shù)的操作。
2.1for循環(huán)語法:
FOR loop_counter IN [REVERSE] low_value..high_value LOOP
-- statements to be executed
END LOOP;
--簡單理解v:
for 變量 in [reverse]小值..大值 loop --(兩值之間要有兩個點,不能多不能少)
要執(zhí)行的語句;
[exit when 中途退出的條件;]
end loop;
·加上reverse是從大值循環(huán)到小值其中, loop_counter 為循環(huán)計數(shù)器,它可以是任何用戶定義的變量或標識符; low_value 和 high_value 表示循環(huán)計數(shù)器的起始值和終止值; REVERSE 為可選關鍵字,表示倒序循環(huán)。
2.2for循環(huán)示例
示例1.循環(huán)打印1-10,代碼如下:
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;輸出結(jié)果如下:

示例2.循環(huán)打印1+2+3+4...+10=55這個式子,代碼如下:
declare
v2 int:=0;
begin
for a in 1..9 loop
v2:=v2+a;
dbms_output.put(a||'+');
end loop;
dbms_output.put_line('10='||(v2+10));
end;輸出結(jié)果如下:

示例3.打印直角三角形,如下圖所示,

代碼如下:
begin
for i in 1..5 loop--控制層數(shù)
for j in 1..i loop--控制每一層的星數(shù)
dbms_output.put('* ');
end loop;
dbms_output.put_line('');
end loop;
end;輸出結(jié)果和上圖一致。
示例4.打印九九乘法表,代碼如下:
begin
for i in 1..9 loop
for j in 1..i loop
dbms_output.put(j||'×'||i||'='||j*i||' ');
end loop;
dbms_output.put_line('');
end loop;
end;輸出結(jié)果如下:

三、while循環(huán)
WHILE 循環(huán)是一種基于條件表達式的循環(huán)結(jié)構(gòu),只要條件表達式的結(jié)果為 TRUE,則會一直執(zhí)行循環(huán)內(nèi)的語句,直到條件變?yōu)?FALSE 才停止循環(huán)。也就是說它會根據(jù)指定條件重復執(zhí)行某一段代碼,直到條件不成立為止。
3.1while循環(huán)語法
其基本語法如下:
WHILE condition LOOP
-- statements to be executed
END LOOP;
--簡單理解v:
while 條件 --進入循環(huán)的條件
loop
要執(zhí)行的語句;
[exit when 退出條件;]--中途退出的條件
end loop;其中, condition 是一個布爾表達式,當其值為 TRUE 時會執(zhí)行循環(huán)內(nèi)的語句。
3.2while循環(huán)示例
示例1.循環(huán)打印1-10,代碼如下:
declare
v1 int:=1;
begin
while v1<=10 loop
dbms_output.put_line(v1);
--exit when v1=5;
v1:=v1+1;
end loop;
end;輸出結(jié)果如下:

示例2.循環(huán)打印1+2+3+4...+10=55這個式子,代碼如下:
declare
v1 int:=1;
v2 int:=0;
begin
while v1<10 loop
v2:=v2+v1;
dbms_output.put(v1||'+');
v1:=v1+1;
end loop;
dbms_output.put_line('10='||(v2+v1));
end;輸出結(jié)果如下:

示例3.打印九九乘法表,代碼如下:
declare
i int:=1;
j int:=1;
begin
while i<=9 loop j:=1;
while j<=i loop
Dbms_Output.put(i||'*'||j||'='||i*j);
dbms_output.put(' ');
j:=j+1;
end loop;
dbms_output.new_line;
i:=i+1;
end loop;
end;輸出結(jié)果如下:

四、GOTO 循環(huán)
GOTO 循環(huán)是一種標簽控制形式,是一種無條件轉(zhuǎn)移語句,用于跳轉(zhuǎn)到程序中的指定標簽位置。在指定標簽前置了符號“:”后,通過 GOTO+標簽名 的方式實現(xiàn)循環(huán)。
4.1GOTO 循環(huán)語法
其基本語法如下:
<<label>> WHILE condition LOOP statement; [EXIT | EXIT WHEN condition]; -- 跳轉(zhuǎn)至標簽位置 GOTO label; END LOOP;
其中 label 是循環(huán)名稱,condition 和 statement 同 WHILE 循環(huán)的定義。如果要退出循環(huán),可以使用 BREAK 語句或者在 loop 開始位置放置 EXIT 語句。
4.2GOTO 循環(huán)示例
示例1.循環(huán)打印1到10,代碼如下:
DECLARE
i NUMBER := 1;
BEGIN
<<my_loop>> -- 聲明標記名稱my_loop
IF i <= 10 THEN
DBMS_OUTPUT.PUT_LINE(i);
i := i + 1;
GOTO my_loop; -- 跳轉(zhuǎn)到標記名稱為my_loop的位置
END IF;
END;輸出結(jié)果如下:

示例2.打印九九乘法表,代碼如下:
DECLARE
i NUMBER := 1;
j NUMBER := 1;
BEGIN
<<my_loop1>> -- 標記名稱為 my_loop1
IF i <= 9 THEN
<<my_loop2>> -- 標記名稱為 my_loop2
IF j <= i THEN
DBMS_OUTPUT.PUT(i || '*' || j || '=' || i*j || ' ');
j := j + 1;
GOTO my_loop2; -- 轉(zhuǎn)移到標記名稱為 my_loop2 的位置
ELSE
DBMS_OUTPUT.NEW_LINE; -- 換行
j := 1;
i := i + 1;
GOTO my_loop1; -- 轉(zhuǎn)移到標記名稱為 my_loop1 的位置
END IF;
END IF;
END;日常情況使用goto循環(huán)的情況會比較少,我解釋下上面的代碼:在上述代碼中,首先初始化變量 i 和 j 并聲明兩個標記名稱 my_loop1 和 my_loop2 。然后,在第一層循環(huán)中,檢查 i 的值是否小于等于 9。如果是,則進入第二層循環(huán),檢查 j 的值是否小于等于 i 。如果是,則使用 DBMS_OUTPUT.PUT_LINE 函數(shù)輸出乘法表的一項,并將變量 j 加 1。接著使用 GOTO 語句跳轉(zhuǎn)到第二層循環(huán)的最開始位置(即標記名稱為 my_loop2 的地方),繼續(xù)執(zhí)行乘法表循環(huán)。如果 j 的值大于 i ,則輸出一個空行,并將變量 j 重置為 1,將 i 加 1。然后使用 GOTO 語句跳轉(zhuǎn)到第一層循環(huán)的最開始位置(即標記名稱為 my_loop1 的地方),繼續(xù)執(zhí)行乘法表循環(huán)。
最后輸出結(jié)果如下:

注意:
GOTO 循環(huán)是基于 PL/SQL 語言的特性,在 Oracle 數(shù)據(jù)庫的多個版本中都支持。
具體地說,GOTO 循環(huán)是在 Oracle Database 11g Release 2 和之后版本中引入的新特性。 如果使用的是 Oracle 數(shù)據(jù)庫較老的版本,可能不支持該特性。
雖然使用 GOTO 可以實現(xiàn)類似于循環(huán)的功能,但是它也可能會影響代碼的可讀性和維護性,代碼設計時應優(yōu)先考慮使用更好的循環(huán)結(jié)構(gòu)方式(如WHILE循環(huán)、FOR循環(huán)等)來實現(xiàn)控制流程。同時,為了提高代碼執(zhí)行效率,應當盡量避免在PL/SQL中過度使用 GOTO 語句。
在PL/SQL中,GO和CONTINUE語句可以使用類似的方式來實現(xiàn)迭代。通常情況下,使用帶有明確退出條件的循環(huán)比使用GOTO更容易理解和調(diào)試。
總結(jié)
到此這篇關于Oracle數(shù)據(jù)庫中的循環(huán)語法及舉例的文章就介紹到這了,更多相關Oracle循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Oracle數(shù)據(jù)庫中ORDER BY排序和查詢按IN條件的順序輸出
這篇文章主要介紹了Oracle數(shù)據(jù)庫中ORDER BY排序和查詢按IN條件的順序輸出的方法,其中ORDER BY的排序結(jié)果需要注意其是否穩(wěn)定,需要的朋友可以參考下2015-11-11
Oracle PL/SQL中“表或視圖不存在“錯誤的解決方案
在Oracle PL/SQL開發(fā)中,許多開發(fā)者都遇到過這個令人困惑的錯誤表或視圖不存在,這個錯誤看似簡單,但背后可能有多種原因,特別是當表確實存在時,這個錯誤更讓人摸不著頭腦,所以本文介紹了詳細的解決方案,需要的朋友可以參考下2025-04-04

