天天看點

PL/SQL控制語句

12-10

IF-THEN-ELSE 語句

IF語句:包含IF-THEN和IF-THEN-ELSE

ELSIF語句:如果IF不成立 允許怎樣

循環1

IF condition

THEN

.....

END IF;

例子

declare

v_count NUMBER(10):=0;

v_empno NUMBER(4):=7888;

begin

select count(1) into v_count from emp where empno=v_empno;

IF v_empno=0

insert into emp(empno,ename,job,hiredate,sal,deptno) values(v_empno,'張三','經理',TRUNC(SYSDATE),1000,20);

commit;

exception

when others

then

dbms_output.put_line(SQLERRM);

end;

循環2

......

ELSE

v_count NUMBER(10):=0;

v_empno NUMBER(4):=7888;

select count(1) into v_count from emp where empno = v_empno;

IF v_count=0

THEN 

insert into emp (empno,ename,job,hiredate,sal,deptno) values(v_empno,'張三','經理' ,TRUNC(SYSDATE),1000,20);

update emp set ename='張三',job='經理',hiredate=TRUNC(SYSDATE),sal=1000,deptno=20  where empno=v_empno;

嵌套IF語句

v_sal NUMBER(7,2);

v_deptno NUMBER(2);

v_job varchar2(9);

select deptno,v_job,sal into v_deptno,v_job,v_sal from emp where empno=&empno;

IF v_deptno=20

IF v_job='CLERK'

v_sal := v_sal *(1+0.12);

ELSIF v_job='ANALYST'

v_sal := v_sal * (1+0.19);

dbms_output.put_line('僅部門編号為20的員工才能加薪');

IF-THEN-ELSIF語句

IF condition-1

statements-1

ELSIF condition-N

statements-N

[ELSE

else_statements]

end if;

當開始IF條件為false或者null時  則elsif 就執行另一個條件 包含多個elsif語句時 隻有當有是true時 才會被執行 然後忽略掉所有其他的ELSIF 語句 進入end if。如果所有的elsif都失敗  則進入else語句

例子   有問題   待解決

v_character char(1);

v_character := '&tmpvar';

IF    v_character = 'A'

dbms_output.put_line('目前輸出字元串:'|| v_character);

ELSIF v_character = 'B'

ELSIF v_character = 'C'

else

dbms_output.put_line('不是1-3之間的字元');

END;

 18  /

輸入 tmpvar 的值:  A

原值    4:      v_character := &tmpvar;

新值    4:      v_character := A;

        v_character := A;

                       *

第 4 行出現錯誤:

ORA-06550: 第 4 行, 第 17 列:

PLS-00201: 必須聲明辨別符 'A'

ORA-06550: 第 4 行, 第 2 列:

PL/SQL: Statement ignored

v_character := &tmpvar;

IF    v_character = '1'

ELSIF v_character = '2'

ELSIF v_character = '3'

卻可以執行 

輸入 tmpvar 的值:  1

新值    4:      v_character := 1;

目前輸出字元串:1

PL/SQL 過程已成功完成。

這樣就對了

輸入 tmpvar 的值:  'A'

新值    4:      v_character := 'A';

SQL> declare

  2     v_character char(1);

  3  begin

  4     v_character := '&tmpvar';

  5     IF    v_character = 'A'

  6     THEN

  7             dbms_output.put_line('目前輸出字元串:'|| v_character);

  8     ELSIF v_character = 'B'

  9     THEN

 10             dbms_output.put_line('目前輸出字元串:'|| v_character);

 11     ELSIF v_character = 'C'

 12     THEN

 13             dbms_output.put_line('目前輸出字元串:'|| v_character);

 14     else

 15             dbms_output.put_line('不是1-3之間的字元');

 16     END IF;

 17  END;

原值    4:      v_character := '&tmpvar';

這樣也可以

12-11 

CASE 語句分為兩種類型

簡單CASE語句:簡單的CASE語句的選擇器是一個變量或是一個傳回有效資料類型的函數,選擇器不可以是布爾類型

搜尋CASE語句:搜尋CASE語句的選擇器是布爾類型的變量或是傳回布爾型的函數,預設的選擇器為true,當搜尋一個true表達式時,可以省略掉選擇器的定義

CASE 。。。。

WHEN .......THEN

.........;

WHEN.........THEN

END CASE;

v_job varchar2(30);

v_empno NUMBER(4):=&empno;

select job into v_job from emp where empno = v_empno;

CASE v_job

WHEN 'CLERK'

update emp set sal=sal*(1+0.15)

where empno=v_empno;

dbms_output.put_line('為普通職員加薪15%');

WHEN 'MANAGER'

update emp set sal=sal*(1+0.20)

dbms_output.put_line('為管理人員加薪20%');

WHEN 'SALESMAN'

update emp set sal=sal*(1+0.22)

dbms_output.put_line('為銷售人員加薪22%');

dbms_output.put_line('員工職級不再加薪的行列');

end case;

搜尋CASE語句

CASE [TRUE | FALSE]

WHEN ......THEN

.............;

WHEN.......THEN

v_sal NUMBER(10,2);

v_empno number(10):=&empno;

select sal into v_sal from emp where empno = v_empno;

CASE

WHEN v_sal BETWEEN 1000 AND 1500

dbms_output.put_line('員工級别:初級職員');

WHEN v_sal BETWEEN 1500 AND 3000

dbms_output.put_line('員工級别:中級管理');

WHEN v_sal BETWEEN 3000 AND 5000

dbms_output.put_line('員工級别:進階經理');

dbms_output.put_line('不在級别範圍之内');

循環控制語句

簡單的loop循環:loop-end loop

數字式for循環:指定循環要執行的次數

while循環:僅當特定的循環滿足時才執行循環,當條件不再滿足時循環終止 

exit語句

exit語句:直接退出循環

exit when:當when指定的條件滿足時退出循環

1.

loop

end loop;

2.

.....;

IF ......THEN;

EXIT;

END LOOP;

例子 

v_count number(2):=0;

v_count:=v_count+1;

dbms_output.put_line('行' || v_count || ': Hello PLSQL');

IF v_count=10

dbms_output.put_line('循環已經退出了');

..........;

exit when .......;

v_count number(2):=0;

exit when v_count=10;

dbms_output.put_line('循環已經退出');

使用continue 繼續執行循環

continue 不會中斷目前循環的執行,但是continue不會馬上退出循環,而是将循環執行跳轉到語句的開頭開始下一次循環,continue 允許跳過部分循環執行的代碼重新開始另一次循環。

例子 在一個輸出累加循環的代碼中 如果循環體計數大于3,則執行額外的輸出代碼,如果小于3,将跳過部分代碼的執行。

x number:=0;

dbms_output.put_line('内部循環值:x' || TO_CHAR(x));

x := x+1;

IF x < 3

continue;

dbms_output.put_line('continue之後的值: x=' || TO_CHAR(x));

exit when x = 5;

dbms_output.put_line('循環體結束後的值: x = ' || TO_CHAR(x));

continue when 例子

continue when x < 3;

while-loop 循環

loop-end loop類似的代碼總能被執行至少一次  這種類型的循環也稱為出口值守循環。

while-loop循環在代碼之前先判斷一個條件,如果條件一開始就為假,那麼一次循環也不執行,這種類型叫做 入口值守循環。

while ........loop

v_count PLS_INTEGER :=1;

while v_count <= 5

dbms_output.put_line('while循環索引值:' || v_count);

for-loop 循環分為:

1.數字for循環

2.遊标for循環

v_total integer:=0;

for i in 1 .. 3

v_total := v_total +1;

dbms_output.put_line('循環計數器值:'|| i);

dbms_output.put_line('循環總計:' || v_total);

 11  /

循環計數器值:1

循環計數器值:2

循環計數器值:3

循環總計:3

預設循環計數是從低到高的

使用reverse 循環過程将按高到低的順序執行

v_total integer:=0;

for i in reverse 1 .. 3

1 .. 3 是循環的邊界值

邊界值可以是變量,表達式,隻要是可以指派的數字

v_counter integer := &counter;

for i in 1 .. v_counter

dbms_output.put_line('循環計數:'|| i);

GOTO語句和标簽

GOTO語句是一個無條件跳轉語句,它可以将程式的執行流程跳轉到某個标簽。

p varchar2(30);

n PLS_INTEGER := 37;

for j in 2 .. ROUND(SQRT(n)) 

IF n MOD j=0 THEN

p:='不是素數';

GOTO print_now;

p := '是一個素數';

<<print_now>>

dbms_output.put_line(TO_CHAR(n) || p );

GOTO語句可以向上或向下跳轉

v_counter INT:=0;

<<outer>>

v_counter := v_counter +1;

dbms_output.put_line('循環計數器'|| v_counter);

if v_counter < 5

GOTO outer;

NULL語句 表示什麼也不執行

null與标簽使用示例

done boolean;

for i in 1 .. 50

if done

GOTO end_loop;

<<end_loop>>

NULL;

在異常語句塊中使用null

v_result int := 0;

v_result:=16/0;

dbms_output.put_line('現在時間是 :' || TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'));

EXCEPTION 

WHEN OTHERS

上面的故意制造被0除  跳到異常處理,null語句表示出異常不進行任何的處理

      本文轉自潘闊 51CTO部落格,原文連結:http://blog.51cto.com/pankuo/1630246,如需轉載請自行聯系原作者