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

THEN

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

END IF;

commit;

exception

when others

then

dbms_output.put_line(SQLERRM);

end;


循环2

IF condition

THEN

......

ELSE

......

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_count=0

THEN 

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

ELSE

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

END IF;

commit;

exception

when others

then

dbms_output.put_line(SQLERRM);

end;


嵌套IF语句


declare

v_sal NUMBER(7,2);

v_deptno NUMBER(2);

v_job varchar2(9);

begin

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

IF v_deptno=20

THEN

IF v_job='CLERK'

THEN

v_sal := v_sal *(1+0.12);

ELSIF v_job='ANALYST'

THEN

v_sal := v_sal * (1+0.19);

END IF;

ELSE

dbms_output.put_line('仅部门编号为20的员工才能加薪');

END IF;

end;




IF-THEN-ELSIF语句


IF condition-1

THEN

statements-1

ELSIF condition-N

THEN

statements-N

[ELSE

else_statements]

end if;


当开始IF条件为false或者null时  则elsif 就执行另一个条件 包含多个elsif语句时 只有当有是true时 才会被执行 然后忽略掉所有其他的ELSIF 语句 进入end if。如果所有的elsif都失败  则进入else语句


例子   有问题   待解决

declare

v_character char(1);

begin

v_character := '&tmpvar';

IF    v_character = 'A'

THEN

dbms_output.put_line('当前输出字符串:'|| v_character);

ELSIF v_character = 'B'

THEN

dbms_output.put_line('当前输出字符串:'|| v_character);

ELSIF v_character = 'C'

THEN

dbms_output.put_line('当前输出字符串:'|| v_character);

else

dbms_output.put_line('不是1-3之间的字符');

END IF;

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



declare

v_character char(1);

begin

v_character := &tmpvar;

IF    v_character = '1'

THEN

dbms_output.put_line('当前输出字符串:'|| v_character);

ELSIF v_character = '2'

THEN

dbms_output.put_line('当前输出字符串:'|| v_character);

ELSIF v_character = '3'

THEN

dbms_output.put_line('当前输出字符串:'|| v_character);

else

dbms_output.put_line('不是1-3之间的字符');

END IF;

END;


却可以执行 

 18  /

输入 tmpvar 的值:  1

原值    4:      v_character := &tmpvar;

新值    4:      v_character := 1;

当前输出字符串:1


PL/SQL 过程已成功完成。

 

这样就对了


输入 tmpvar 的值:  'A'

原值    4:      v_character := &tmpvar;

新值    4:      v_character := 'A';


PL/SQL 过程已成功完成。



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;

 18  /

输入 tmpvar 的值:  A

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

新值    4:      v_character := 'A';


PL/SQL 过程已成功完成。


这样也可以



12-11 

CASE 语句分为两种类型

简单CASE语句:简单的CASE语句的选择器是一个变量或是一个返回有效数据类型的函数,选择器不可以是布尔类型

搜索CASE语句:搜索CASE语句的选择器是布尔类型的变量或是返回布尔型的函数,默认的选择器为true,当搜索一个true表达式时,可以省略掉选择器的定义


CASE 。。。。

WHEN .......THEN

.........;

WHEN.........THEN

.........;

ELSE

.........;

END CASE;



declare

v_job varchar2(30);

v_empno NUMBER(4):=&empno;

begin

select job into v_job from emp where empno = v_empno;

CASE v_job

WHEN 'CLERK'

THEN

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

where empno=v_empno;

dbms_output.put_line('为普通职员加薪15%');

WHEN 'MANAGER'

THEN

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

where empno=v_empno;

dbms_output.put_line('为管理人员加薪20%');

WHEN 'SALESMAN'

THEN

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

where empno=v_empno;

dbms_output.put_line('为销售人员加薪22%');

else

dbms_output.put_line('员工职级不再加薪的行列');

end case;

end;


搜索CASE语句

CASE [TRUE | FALSE]

WHEN ......THEN

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

WHEN.......THEN

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

ELSE

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

END CASE;



declare

v_sal NUMBER(10,2);

v_empno number(10):=&empno;

begin

select sal into v_sal from emp where empno = v_empno;

CASE

WHEN v_sal BETWEEN 1000 AND 1500

THEN

dbms_output.put_line('员工级别:初级职员');

WHEN v_sal BETWEEN 1500 AND 3000

THEN

dbms_output.put_line('员工级别:中级管理');

WHEN v_sal BETWEEN 3000 AND 5000

THEN

dbms_output.put_line('员工级别:高级经理');

ELSE

dbms_output.put_line('不在级别范围之内');

END CASE;

END;



循环控制语句


简单的loop循环:loop-end loop

数字式for循环:指定循环要执行的次数

while循环:仅当特定的循环满足时才执行循环,当条件不再满足时循环终止 


exit语句

exit语句:直接退出循环

exit when:当when指定的条件满足时退出循环


1.

loop

.........;

end loop;


2.

loop

.....;

.....;

IF ......THEN;

EXIT;

END IF;

END LOOP;


例子 

declare

v_count number(2):=0;

begin

loop

v_count:=v_count+1;

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

IF v_count=10

THEN

EXIT;

end if;

end loop;

dbms_output.put_line('循环已经退出了');

end;




loop

..........;

..........;

exit when .......;

end loop;



例子

declare

v_count number(2):=0;

begin

loop

v_count:=v_count+1;

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

exit when v_count=10;

end loop;

dbms_output.put_line('循环已经退出');

end;




使用continue 继续执行循环

continue 不会中断当前循环的执行,但是continue不会马上退出循环,而是将循环执行跳转到语句的开头开始下一次循环,continue 允许跳过部分循环执行的代码重新开始另一次循环。


例子 在一个输出累加循环的代码中 如果循环体计数大于3,则执行额外的输出代码,如果小于3,将跳过部分代码的执行。


declare

x number:=0;

begin

loop

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

x := x+1;

IF x < 3

THEN

continue;

end if;

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

exit when x = 5;

end loop;

dbms_output.put_line('循环体结束后的值: x = ' || TO_CHAR(x));

end;


continue when 例子


declare

x number:=0;

begin

loop

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

x := x+1;

continue when x < 3;

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

exit when x = 5;

end loop;

dbms_output.put_line('循环体结束后的值: x = ' || TO_CHAR(x));

end;



while-loop 循环


loop-end loop类似的代码总能被执行至少一次  这种类型的循环也称为出口值守循环。


while-loop循环在代码之前先判断一个条件,如果条件一开始就为假,那么一次循环也不执行,这种类型叫做 入口值守循环。



while ........loop

..........;

..........;

end loop;


declare

v_count PLS_INTEGER :=1;

begin

while v_count <= 5

loop

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

v_count:=v_count+1;

end loop;

end;



for-loop 循环分为:

1.数字for循环

2.游标for循环


declare

v_total integer:=0;

begin

for i in 1 .. 3

loop

v_total := v_total +1;

dbms_output.put_line('循环计数器值:'|| i);

end loop;

dbms_output.put_line('循环总计:' || v_total);

end;


 11  /

循环计数器值:1

循环计数器值:2

循环计数器值:3

循环总计:3


PL/SQL 过程已成功完成。



默认循环计数是从低到高的

使用reverse 循环过程将按高到低的顺序执行


declare

v_total integer:=0;

begin

for i in reverse 1 .. 3

loop

v_total := v_total +1;

dbms_output.put_line('循环计数器值:'|| i);

end loop;

dbms_output.put_line('循环总计:' || v_total);

end;


循环计数器值:3

循环计数器值:2

循环计数器值:1

循环总计:3


PL/SQL 过程已成功完成。


1 .. 3 是循环的边界值

边界值可以是变量,表达式,只要是可以赋值的数字


declare

v_counter integer := &counter;

begin

for i in 1 .. v_counter

loop

dbms_output.put_line('循环计数:'|| i);

end loop;

end;



GOTO语句和标签

GOTO语句是一个无条件跳转语句,它可以将程序的执行流程跳转到某个标签。


declare

p varchar2(30);

n PLS_INTEGER := 37;

begin

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

loop

IF n MOD j=0 THEN

p:='不是素数';

GOTO print_now;

END IF;

end loop;

p := '是一个素数';

<<print_now>>

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

end;


GOTO语句可以向上或向下跳转


declare

v_counter INT:=0;

begin

<<outer>>

v_counter := v_counter +1;

dbms_output.put_line('循环计数器'|| v_counter);

if v_counter < 5

then

GOTO outer;

end if;

end;


NULL语句 表示什么也不执行



null与标签使用示例

declare

done boolean;

begin

for i in 1 .. 50

loop

if done

then

GOTO end_loop;

end if;

<<end_loop>>

NULL;

end loop;

end;




在异常语句块中使用null


declare

v_result int := 0;

begin

v_result:=16/0;

dbms_output.put_line('现在时间是 :' || TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'));

EXCEPTION 

WHEN OTHERS

THEN

NULL;

END;


上面的故意制造被0除  跳到异常处理,null语句表示出异常不进行任何的处理