--=======================
-- ? PL/SQL --> 流程控制
--=======================
?
??? 類似于高級語言,流程控制語句是 PL / SQL 語言的重要組成部分。這些流程控制語句使得 PL / SQL 加大了代碼的靈活性和多樣性,大大簡化了
程序的編寫。下面將列出流程控制語句并給出具體事例。
???
一、順序結構
??? 按代碼的書寫順序依次執行
??? -- 在下面的示例中將逐步執行代碼
??????? scott@ORCL > declare v_ename varchar2 ( 20 );
??????? ? 2 ? v_job emp . job % type ;
??????? ? 3 ? v_no ? emp . empno % type ;
??????? ? 4 ? begin
??????? ? 5 ??? v_no :=& inputno ;
??????? ? 6 ??? select ename , job into v_ename , v_job from emp where empno = v_no ;
??????? ? 7 ??? dbms_output . put_line ( 'Employee Name: ' || v_ename );
??????? ? 8 ??? dbms_output . put_line ( 'Employee Job : ' || v_job );
??????? ? 9 ? end ;
??????? ? 10 ? /
??????? Enter value for inputno : 7788
??????? old ?? 5 : ?? v_no :=& inputno ;
??????? new ?? 5 : ?? v_no := 7788 ;
??????? Employee Name : SCOTT
??????? Employee Job : ANALYST
?
??????? PL / SQL procedure successfully completed . ???
二、條件分支結構
??? 1. IF ... THEN ... END IF
??????? IF condition THEN
??????????? statement
??????? END IF ;
?
??????? 判斷 condition 是否成立,成立就執行 IF 與 END IF 之間的語句。
???
??????? -- 例:輸入員工編號,查詢其工資,如果他們的職位是 CLERK ,則工資增加 % ,再顯示修改前后的工資數。
?
??????????? DECLARE
??????????????? v_empid emp . empno % TYPE ;
??????????????? v_job emp . job % TYPE ;
??????????????? v_old_sal emp . sal % TYPE ;
??????????????? v_new_sal emp . sal % TYPE ;
??????????? BEGIN
??????????????? v_empid :=& inputid ;
??????????????? SELECT job , sal INTO v_job , v_old_sal FROM emp WHERE empno = v_empid ;
??????????????? IF v_job = 'CLERK' THEN
??????????????????? v_new_sal := v_old_sal * 1.1 ;
??????????????????? UPDATE emp SET sal = v_new_sal WHERE empno = v_empid ;
??????????????????? DBMS_OUTPUT . PUT_LINE ( 'Old sal:' || v_old_sal );
??????????????????? DBMS_OUTPUT . PUT_LINE ( 'New sal:' || v_new_sal );
??????????????? END IF ;
??????????? EXCEPTION
??????????????? WHEN NO_DATA_FOUND THEN
??????????????????? DBMS_OUTPUT . PUT_LINE ( 'Not FOUND RECORD' );
??????????? END ;
??????????? /
?
??? 2. IF ... THEN ... ELSE ... END IF
??????? IF condition THEN
??????????? statements1 ;
??????? ELSE
??????????? statements2 ;
??????? END IF ;
?
??????? 判斷 condition 是否成立,成立就執行 IF 與 ELSE 之間的語句,
??????? 否則執行 ELSE 與 END IF 之間的語句。
?
??????? -- 例:輸入員工編號 , 查詢其工資 , 如果他們的職位是 CLERK, 則工資增加 %, 如果不是 CLERK, 工資增加 8%, 再顯示修改前后的工資數。
?
??????????? DECLARE
??????????????? v_empid emp . empno % TYPE ;
??????????????? v_job emp . job % TYPE ;
??????????????? v_old_sal emp . sal % TYPE ;
??????????????? v_new_sal emp . sal % TYPE ;
??????????? BEGIN
??????????????? v_empid :=& inputid ;
??????????????? SELECT job , sal INTO v_job , v_old_sal FROM emp WHERE empno = v_empid ;
??????????????? IF v_job = 'CLERK' THEN
??????????????????? v_new_sal := v_old_sal * 1.1 ;
??????????????? ELSE
??????????????????? v_new_sal := v_old_sal * 1.08 ;
??????????????? END IF ;
?
??????????????? UPDATE emp SET sal = v_new_sal WHERE empno = v_empid ;
??????????????? DBMS_OUTPUT . PUT_LINE ( 'Old sal:' || v_old_sal );
??????????????? DBMS_OUTPUT . PUT_LINE ( 'New sal:' || v_new_sal );
?
??????????? EXCEPTION
??????????????? WHEN NO_DATA_FOUND THEN
??????????????????? DBMS_OUTPUT . PUT_LINE ( 'Not FOUND RECORD' );
??????????? END ;
??????????? /
?
??? 3. IF ... THEN ... ELSIF ... THEN ... ELSE ... END IF
??????? IF condition1 THEN
??????????? statements1 ;
??????? ELSIF condition2 THEN
??????????? statements2 ;
??????? ELSE
??????????? else_statements ;
??????? END IF ;
?
??????? -- 例 : 輸入員工編號 , 查詢其工資 , 如果其職位是 CLERK, 則工資增加 %, 如果是 SALESMAN 工資增加 %, 其它的加 %, 顯示修改前后的工資數。
?
??????????? DECLARE
??????????????? v_empid emp . empno % TYPE ;
??????????????? v_job emp . job % TYPE ;
??????????????? v_old_sal emp . sal % TYPE ;
??????????????? v_new_sal emp . sal % TYPE ;
??????????? BEGIN
??????????????? v_empid :=& inputid ;
??????????????? SELECT job , sal INTO v_job , v_old_sal FROM emp WHERE empno = v_empid ;
??????????????? IF v_job = 'CLERK' THEN
??????????????????? v_new_sal := v_old_sal * 1.1 ;
??????????????? ELSIF v_job = 'SALESMAN' THEN
??????????????????? v_new_sal := v_old_sal * 1.08 ;
??????????????? ELSE
??????????????????? v_new_sal := v_old_sal * 1.05 ;
??????????????? END IF ;
?
??????????????? UPDATE emp SET sal = v_new_sal WHERE empno = v_empid ;
??????????????? DBMS_OUTPUT . PUT_LINE ( 'Old sal:' || v_old_sal );
??????????????? DBMS_OUTPUT . PUT_LINE ( 'New sal:' || v_new_sal );
?
??????????? EXCEPTION
??????????????? WHEN NO_DATA_FOUND THEN
??????????????????? DBMS_OUTPUT . PUT_LINE ( 'Not FOUND RECORD' );
??????????? END ;
??????????? /
???????
??? 4. 等值比較的 CASE 多分支
???????
??????? CASE expression
??????? ??? WHEN result_1 THEN
??????????? statements1 ;
??????? ??? WHEN result_2 THEN
??????????? statemnts2 ;
??????? ????? ......
??????? ??? [ELSE
??????????? else_statements;]
??????? END CASE ;
???????
??????? -- 使用 case 分支完成前面的示例
??????? -- 例 : 輸入員工編號 , 查詢其工資 , 如果其職位是 CLERK, 則工資增加 %, 如果是 SALESMAN 工資增加 %, 其它的加 %, 顯示修改前后的工資數。
??????????? DECLARE
??????????????? v_empid emp . empno % TYPE ;
??????????????? v_job emp . job % TYPE ;
??????????????? v_old_sal emp . sal % TYPE ;
??????????????? v_new_sal emp . sal % TYPE ;
??????????? BEGIN
??????????????? v_empid :=& inputid ;
??????????????? SELECT job , sal INTO v_job , v_old_sal FROM emp WHERE empno = v_empid ;
??????????????? CASE v_job
??????????????????? WHEN 'CLERK' THEN
??????????????????? v_new_sal := v_old_sal * 1.1 ;
??????????????????? WHEN 'SALESMAN' THEN
??????????????????? v_new_sal := v_old_sal * 1.08 ;
??????????????????? ELSE
??????????????????? v_new_sal := v_old_sal * 1.05 ;
??????????????? END CASE ;
?
??????????????? UPDATE emp SET sal = v_new_sal WHERE empno = v_empid ;
??????????????? DBMS_OUTPUT . PUT_LINE ( 'Old sal:' || v_old_sal );
??????????????? DBMS_OUTPUT . PUT_LINE ( 'New sal:' || v_new_sal );
?
??????????? EXCEPTION
??????????????? WHEN NO_DATA_FOUND THEN
??????????????????? DBMS_OUTPUT . PUT_LINE ( 'Not FOUND RECORD' );
??????????? END ;
??????????? /
?
??? 5. 條件比較的 CASE 語句
??????? CASE
??????????? WHEN expression_1 THEN
??????????????? statements1 ;
??????????? WHEN expression_2 THEN
??????????????? statements2 ;
??????????? WHEN expression_3 THEN
??????????????? statements3 ;
? ?????????????? ......
??????????? [ELSE
??????????????? else_statements ; ]
??????? END CASE
???????
??????? -- 使用 case 分支完成前面的示例,僅僅列出 case 部分
??????????? CASE
??????????????? WHEN v_job = 'CLERK' THEN
??????????????? v_new_sal := v_old_sal * 1.1 ;
??????????????? WHEN v_job = 'SALESMAN' THEN
??????????????? v_new_sal := v_old_sal * 1.08 ;
??????????????? ELSE
??????????????? v_new_sal := v_old_sal * 1.05 ;
??????????? END CASE ;
?
三、循環結構
??? 1.LOOP 循環
???????
??????? LOOP
??????????? statement ;
??? ??????? EXIT [WHEN condition];
??????? END LOOP;
?
??????? -- 例:用 LOOP 寫一個程序求 1 ++++ . . . +10 之和
?
??????????? DECLARE
??????????????? v_n INT := 1 ;
??????????????? v_s INT := 0 ;
??????????? BEGIN
??????????????? LOOP
??????????????????? v_s := v_s + v_n ;
??????????????????? v_n := v_n + 1 ;
??????????????????? EXIT WHEN v_n > 10 ;
??????????????? END LOOP ; ??
??????????????? DBMS_OUTPUT . PUT_LINE ( '1+2+3+...+10=' || v_s );
??????????? END ;
??????????? /
?
??? 2.WHILE 循環
???
??????? WHIEL condition LOOP
??????????? statement;
??????? END LOOP;
?
??????? -- 下面使用 while 循環完成 loop 循環中的示例
???????????
??????????? DECLARE
??????????????? v_s NUMBER := 0 ;
??????????????? v_n NUMBER := 1 ;
??????????? BEGIN
??????????????? WHILE v_n <= 10 LOOP
??????????????????? v_s := v_s + v_n ;
??????????????????? v_n := v_n + 1 ;
??????????????? END LOOP ;
??????????????? DBMS_OUTPUT . PUT_LINE ( '1+2+3+...+10=' || v_s );
??????????? END ;
??????????? /
?
??? 3.FOR 循環
???????
??????? FOR loop_index IN [reverse] lowest_number .. highest_number LOOP
??????????? statements ;
??????? END LOOP ;
???????
??????? -- 下面使用 for 循環完成 loop 循環中的示例
??????????? DECLARE
??????????????? v_s NUMBER := 0 ;
??????????? BEGIN
??????????????? FOR v_n IN 1 . .10 LOOP
??????????????????? v_s := v_s + v_n ;
??????????????????? DBMS_OUTPUT . PUT_LINE ( v_n );
??????????????? END LOOP ;
??????????? DBMS_OUTPUT . PUT_LINE ( '1+2+3+...+10=' || v_s );
??????????? END ;
??????????? / ??
?
??????????? DECLARE
??????????????? v_s NUMBER := 0 ;
??????????? BEGIN
??????????????? FOR v_n IN REVERSE 1 . .10 LOOP ??? -- 注意 reverse 是反向循環,即從到
??????????????????? v_s := v_s + v_n ;
??????????????????? DBMS_OUTPUT . PUT_LINE ( v_n );
??????????????? END LOOP ;
??????????? DBMS_OUTPUT . PUT_LINE ( '1+2+3+...+10=' || v_s );
??????????? END ;
??????????? /
?
四、 GOTO 語句
??? GOTO label_name
?
??????? -- 下面使用 goto 語句完成 loop 循環中的示例
??????????? DECLARE
??????????????? v_n NUMBER := 1 ;
??????? ??????? v_s NUMBER := 0 ;
??????????? BEGIN
??????????????? LOOP
??????????????????? v_s := v_s + v_n ;
??????????????????? v_n := v_n + 1 ;
??????????????????? IF v_n > 10 THEN
??????????????????????? GOTO out ;
??????????????????? END IF ;
??????????????? END LOOP ;
??????????????? << out >>
??????????????? DBMS_OUTPUT . PUT_LINE ( '1+2+3+...+10=' || v_s );
??????????????? END ;
??????????????? /
?
??? 使用 GOTO 語句應注意:
??????? 標號后至少要有一條語句
??????? PL/SQL 塊內可以相互跳轉,內層塊可以跳到外層塊,但外層塊不能跳到內層塊
??????? 不能從某一 IF 語句外部跳到其內部
??????? 不能從某一循環外跳到其內部
??????? 不能從某一子程序外跳到其內
?
五、 NULL
??? NULL 語句不會執行任何操作,并且會直接將控制傳遞到下一條語句,使用 NULL 語句主要是提高程序的可閱讀性
??????? -- 如下面的示例
??????????? DECLARE
??????????????? v_sal emp . sal % TYPE ;
??????????????? v_ename emp . ename % TYPE ;
??????????? BEGIN
??????????????? SELECT ename , sal into v_ename , v_sal
??????????????? FROM emp WHERE empno =& inputno ;
??????????????? IF v_sal < 3000 then
??????????????????? UPDATE emp SET comm = sal * 1.2 WHERE ename = v_ename ;
??????????????? ELSE
??????????????????? NULL;
??????????????? END IF ;
??????????? END ;
??????????? /
???????????
六、更多參考
? ??? ?
有關 SQL 請參考
??????? SQL 基礎--> 子查詢
??????? SQL 基礎--> 多表查詢
SQL 基礎--> ROLLUP 與CUBE 運算符實現數據匯總
SQL 基礎--> 層次化查詢(START BY ... CONNECT BY PRIOR)
?
??? 有關 PL/SQL 請參考
??????? PL/SQL --> 語言基礎
?
?
?
?
?
?
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
