Oracle數(shù)據(jù)庫中的循環(huán)語法及舉例
前言
在 Oracle 數(shù)據(jù)庫中,提供了多種循環(huán)類型用于實現(xiàn)不同的業(yè)務(wù)邏輯需求。我們可以使用 PL/SQL 中的循環(huán)語句來實現(xiàn)反復(fù)執(zhí)行一段代碼塊的目的。PL/SQL 是一種過程化語言,提供了完善的控制流結(jié)構(gòu),支持多種循環(huán)形式。下面介紹一些常用的循環(huán)語句及其語法和示例。
一、簡單循環(huán)
之所以會被叫做簡單循環(huán):因為它僅是以LOOP關(guān)鍵字開始,以END LOOP語句結(jié)束。要靠循環(huán)體內(nèi)的EXIT、EXIT WHEN或者RETURN來退出循環(huán)(或者有異常拋出)。這種循環(huán)為LOOP 循環(huán),是一種無限循環(huán),它會反復(fù)執(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
是一個可選關(guān)鍵字,可以用來指定跳出循環(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 語句關(guān)閉了游標。這里需要注意,使用游標時需要進行顯式地打開和關(guān)閉操作。下圖是輸出結(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)反復(fù)執(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
為可選關(guān)鍵字,表示倒序循環(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ù)指定條件重復(fù)執(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)的功能,但是它也可能會影響代碼的可讀性和維護性,代碼設(shè)計時應(yīng)優(yōu)先考慮使用更好的循環(huán)結(jié)構(gòu)方式(如WHILE循環(huán)、FOR循環(huán)等)來實現(xiàn)控制流程。同時,為了提高代碼執(zhí)行效率,應(yīng)當盡量避免在PL/SQL中過度使用 GOTO 語句。
在PL/SQL中,GO和CONTINUE語句可以使用類似的方式來實現(xiàn)迭代。通常情況下,使用帶有明確退出條件的循環(huán)比使用GOTO更容易理解和調(diào)試。
總結(jié)
到此這篇關(guān)于Oracle數(shù)據(jù)庫中的循環(huán)語法及舉例的文章就介紹到這了,更多相關(guān)Oracle循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Oracle數(shù)據(jù)庫中ORDER BY排序和查詢按IN條件的順序輸出
這篇文章主要介紹了Oracle數(shù)據(jù)庫中ORDER BY排序和查詢按IN條件的順序輸出的方法,其中ORDER BY的排序結(jié)果需要注意其是否穩(wěn)定,需要的朋友可以參考下2015-11-11Oracle PL/SQL中“表或視圖不存在“錯誤的解決方案
在Oracle PL/SQL開發(fā)中,許多開發(fā)者都遇到過這個令人困惑的錯誤表或視圖不存在,這個錯誤看似簡單,但背后可能有多種原因,特別是當表確實存在時,這個錯誤更讓人摸不著頭腦,所以本文介紹了詳細的解決方案,需要的朋友可以參考下2025-04-04