ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句

本篇主要内容如下:

3.1  条件语句

3.2  CASE 表达式

3.3  循环

3.4  标号和GOTO

3.5  NULL 语句


 

介绍PL/SQL的流程控制语句包括如下三类:

 

控制语句: IF 语句

循环语句: LOOP语句, EXIT语句

顺序语句: GOTO语句, NULL语句

 

3.1  条件语句

  

IF  <布尔表达式 >  THEN
  PL /SQL 和 SQL语句
END  IF;
-- ---------------------
IF  <布尔表达式 >  THEN
  PL /SQL 和 SQL语句
ELSE
  其它语句
END  IF;
-- ---------------------
IF  <布尔表达式 >  THEN
  PL /SQL 和 SQL语句
ELSIF  < 其它布尔表达式 >  THEN
  其它语句
ELSIF  < 其它布尔表达式 >  THEN
  其它语句
ELSE
  其它语句
END  IF;

 

 

提示: ELSIF 不能写成 ELSEIF

例1:

  

DECLARE
    v_empno  employees.employee_id %TYPE : =&empno;
    V_salary employees.salary %TYPE;
    V_comment  VARCHAR2( 35);
BEGIN
    SELECT salary  INTO v_salary  FROM employees 
    WHERE employee_id  = v_empno;
    IF v_salary  <  1500  THEN
       V_comment: =  ' 太少了,加点吧~! ';
   ELSIF v_salary  < 3000  THEN
      V_comment: =  ' 多了点,少点吧~! ';
    ELSE
      V_comment: =  ' 没有薪水~! ';
    END  IF;
   DBMS_OUTPUT.PUT_LINE(V_comment);
   exception
      when no_data_found  then
        DBMS_OUTPUT.PUT_LINE( ' 没有数据~! ');
      when others  then
        DBMS_OUTPUT.PUT_LINE(sqlcode  ||  ' --- '  || sqlerrm);        
END;

 

 

2:

  

DECLARE
   v_first_name   VARCHAR2( 20);
   v_salary  NUMBER( 7, 2);
BEGIN
    SELECT first_name, salary  INTO v_first_name, v_salary  FROM employees
    WHERE employee_id  =  &emp_id;
   DBMS_OUTPUT.PUT_LINE(v_first_name || ' 雇员的工资是 ' ||v_salary);
    IF v_salary  <  10000  THEN
      DBMS_OUTPUT.PUT_LINE( ' 工资低于10000 ');
    ELSE
       IF  10000  <= v_salary  AND v_salary  <  20000  THEN
         DBMS_OUTPUT.PUT_LINE( ' 工资在10000到20000之间 ');
       ELSE
         DBMS_OUTPUT.PUT_LINE( ' 工资高于20000 ');
       END  IF;
    END  IF;
END;

 

 

3:

DECLARE
   v_first_name   VARCHAR2( 20);
   v_hire_date DATE;
   v_bonus  NUMBER( 6, 2);
BEGIN
    SELECT first_name, hire_date  INTO v_first_name, v_hire_date  FROM employees
    WHERE employee_id  =  &emp_id;
    IF v_hire_date  > TO_DATE( ' 01-1月-90 'THEN
      v_bonus : =  800;
   ELSIF v_hire_date  > TO_DATE( ' 01-1月-88 'THEN
      v_bonus : =  1600;
    ELSE
      v_bonus : =  2400;
    END  IF;
   DBMS_OUTPUT.PUT_LINE(v_first_name || ' 雇员的雇佣日期是 ' ||v_hire_date
                                     || ' 、奖金是 ' ||v_bonus);
END;

 

3.2  CASE 表达式

  

-- -------格式一---------
CASE 条件表达式
   WHEN 条件表达式结果1  THEN 
     语句段1
   WHEN 条件表达式结果2  THEN
     语句段2
  ......
   WHEN 条件表达式结果n  THEN
     语句段n
   [ ELSE 条件表达式结果 ]
END;
-- -------格式二---------
CASE 
   WHEN 条件表达式1  THEN
     语句段1
   WHEN 条件表达式2  THEN
     语句段2
  ......
   WHEN 条件表达式n  THEN 
     语句段n
   [ ELSE 语句段 ]
END;

 

 

4:

  

DECLARE
  V_grade  char( 1) : =  UPPER( ' &p_grade ');
  V_appraisal  VARCHAR2( 20);
BEGIN
  V_appraisal : =
   CASE v_grade
     WHEN  ' A '  THEN  ' Excellent '
     WHEN  ' B '  THEN  ' Very Good '
     WHEN  ' C '  THEN  ' Good '
     ELSE  ' No such grade '
   END;
  DBMS_OUTPUT.PUT_LINE( ' Grade: ' ||v_grade || '   Appraisal:  ' || v_appraisal);
END;

 

 

5:

 

DECLARE
   v_first_name employees.first_name %TYPE;
   v_job_id employees.job_id %TYPE;
   v_salary employees.salary %TYPE;
   v_sal_raise  NUMBER( 3, 2);
BEGIN
    SELECT first_name,   job_id,   salary  INTO
          v_first_name, v_job_id, v_salary
    FROM employees  WHERE employee_id  =  &emp_id;
    CASE
       WHEN v_job_id  =  ' PU_CLERK '  THEN
          IF v_salary  <  3000  THEN v_sal_raise : = . 08;
          ELSE v_sal_raise : = . 07;
          END  IF;
       WHEN v_job_id  =  ' SH_CLERK '  THEN
          IF v_salary  <  4000  THEN v_sal_raise : = . 06;
          ELSE v_sal_raise : = . 05;
          END  IF;
       WHEN v_job_id  =  ' ST_CLERK '  THEN
          IF v_salary  <  3500  THEN v_sal_raise : = . 04;
          ELSE v_sal_raise : = . 03;
          END  IF;
       ELSE
         DBMS_OUTPUT.PUT_LINE( ' 该岗位不涨工资:  ' ||v_job_id);
    END  CASE;
   DBMS_OUTPUT.PUT_LINE(v_first_name || ' 的岗位是 ' ||v_job_id
                                     || ' 、的工资是 ' ||v_salary
                                     || ' 、工资涨幅是 ' ||v_sal_raise);
END;

 

 

 

3.3  循环

 1.  简单循环

  

  LOOP
      要执行的语句;
       EXIT  WHEN  <条件语句 >  -- 条件满足,退出循环语句
   END LOOP;

 

 

例 6.

  

DECLARE
     int  NUMBER( 2) : = 0;
BEGIN
   LOOP
       int : =  int  +  1;
      DBMS_OUTPUT.PUT_LINE( ' int 的当前值为: ' || int);
       EXIT  WHEN  int  = 10;
    END LOOP;
END;

 

 

2.  WHILE 循环

WHILE  <布尔表达式 > LOOP
    要执行的语句;
END LOOP;

 

 

 

 

7.

  

DECLARE 
  x  NUMBER : = 1;
BEGIN
    WHILE x <= 10 LOOP
      DBMS_OUTPUT.PUT_LINE( ' X的当前值为: ' ||x);
       x: = x + 1;
    END LOOP;
END;

 

 

3.  数字式循环

  

[ <<循环标签>> ]
FOR 循环计数器  IN  [  REVERSE  ] 下限 .. 上限 LOOP
  要执行的语句;
END LOOP  [ 循环标签 ];

 

 

每循环一次,循环变量自动加1;使用关键字REVERSE,循环变量自动减1。跟在IN REVERSE 后面的数字必须是从小到大的顺序,而且必须是整数,不能是变量或表达式。可以使用EXIT 退出循环。

8.

  

BEGIN
    FOR  int   in  1.. 10 LOOP
       DBMS_OUTPUT.PUT_LINE( ' int 的当前值为:  ' || int);
    END LOOP;
END;

 

 

例 9.

  

CREATE  TABLE temp_table(num_col  NUMBER);

DECLARE
    V_counter  NUMBER : =  10;
BEGIN
    INSERT  INTO temp_table(num_col)  VALUES (v_counter );
    FOR v_counter  IN  20 ..  25 LOOP
       INSERT  INTO temp_table (num_col )  VALUES ( v_counter );
    END LOOP;
    INSERT  INTO temp_table(num_col)  VALUES (v_counter );
    FOR v_counter  IN  REVERSE  20 ..  25 LOOP
       INSERT  INTO temp_table (num_col )  VALUES ( v_counter );
    END LOOP;
END ;

DROP  TABLE temp_table;

 

 

10:

  

DECLARE
   TYPE jobids_varray  IS VARRAY( 12OF  VARCHAR2( 10);  -- 定义一个VARRAY数据类型
   v_jobids JOBIDS_VARRAY;  -- 声明一个具有JOBIDS_VARRAY数据类型的变量
   v_howmany  NUMBER-- 声明一个变量来保存雇员的数量

BEGIN
    -- 用某些job_id值初始化数组
   v_jobids : = jobids_varray( ' FI_ACCOUNT '' FI_MGR '' ST_CLERK '' ST_MAN ');

    -- 用FOR...LOOP...END LOOP循环使用每个数组成员的值
    FOR i  IN v_jobids.FIRST..v_jobids.LAST LOOP

    -- 针对数组中的每个岗位,决定该岗位的雇员的数量
       SELECT  count( *INTO v_howmany  FROM employees  WHERE job_id  = v_jobids(i);
      DBMS_OUTPUT.PUT_LINE (  ' 岗位 ' ||v_jobids(i) ||
                        ' 总共有 ' || TO_CHAR(v_howmany)  ||  ' 个雇员 ');
    END LOOP;
END;

 

 

11 While循环中嵌套loop循环

/* 求100至110之间的素数 */
DECLARE
   v_m  NUMBER : =  101;
   v_i  NUMBER;
   v_n  NUMBER : =  0;
BEGIN
    WHILE v_m  <  110 LOOP
      v_i : =  2;
      LOOP
          IF mod(v_m, v_i)  =  0  THEN
            v_i : =  0;
             EXIT;
          END  IF;
    
         v_i : = v_i  +  1;
          EXIT  WHEN v_i  > v_m  -  1
       END LOOP;
      
       IF v_i  >  0  THEN
         v_n : = v_n  +  1;
         DBMS_OUTPUT.PUT_LINE( ' ' || v_n  ||  ' 个素数是 '  || v_m);
       END  IF;

      v_m : = v_m  +  2;
    END LOOP;
END;

 

3.4  标号和GOTO 

PL/SQLGOTO语句是无条件跳转到指定的标号去的意思。语法如下:

  

GOTO label;
......
<<label >>  /* 标号是用<< >>括起来的标识符  */

 

 

注意,在以下地方使用是不合法的,编译时会出错误。

跳转到非执行语句前面。

跳转到子块中。

跳转到循环语句中。

跳转到条件语句中。

从异常处理部分跳转到执行。

从条件语句的一部分跳转到另一部分。

12:

  

DECLARE
   V_counter  NUMBER : =  1;
BEGIN
   LOOP 
     DBMS_OUTPUT.PUT_LINE( ' V_counter的当前值为: ' ||V_counter);
     V_counter : = v_counter  +  1;
    IF v_counter  >  10  THEN
        GOTO labelOffLOOP;
    END  IF;
    END LOOP;
    <<labelOffLOOP >>
     DBMS_OUTPUT.PUT_LINE( ' V_counter的当前值为: ' ||V_counter);
END;

 

 

13:

DECLARE
   v_i  NUMBER : =  0;
   v_s  NUMBER : =  0;
BEGIN
    <<label_1 >>
   v_i : = v_i  +  1;
    IF v_i  <=  1000  THEN
      v_s : = v_s  + v_i;
       GOTO label_1;
    END  IF;
   DBMS_OUTPUT.PUT_LINE(v_s);
END;

 

3.5  NULL 语句 

在PL/SQL 程序中,NULL语句是一个可执行语句,可以用 null 语句来说明不用做任何事情的意思,相当于一个占位符或不执行任何操作的空语句,可以使某些语句变得有意义,提高程序的可读性,保证其他语句结构的完整性和正确性。如:

14:

 

DECLARE
    ...
BEGIN
    ...
     IF v_num  IS  NULL  THEN
     GOTO labelPrint;
     END  IF;
  …
   <<labelPrint >>
   NULL-- 不需要处理任何数据。
END;

 

 

15:

 

DECLARE
   v_emp_id employees.employee_id %TYPE;
   v_first_name employees.first_name %TYPE;
   v_salary employees.salary %TYPE;
   v_sal_raise  NUMBER( 3, 2);
BEGIN
   v_emp_id : =  &emp_id;
    SELECT first_name, salary  INTO v_first_name, v_salary
    FROM employees  WHERE employee_id  = v_emp_id;
    IF v_salary  <=  3000  THEN
      v_sal_raise : = . 10;
      DBMS_OUTPUT.PUT_LINE(v_first_name || ' 的工资是 ' ||v_salary
                                        || ' 、工资涨幅是 ' ||v_sal_raise);
    ELSE
       NULL;
    END  IF;
END;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值