• 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;
    复制代码
  • 相关阅读:
    创建目录(单个目录和多级子目录)方法
    C++中创建目录
    C/C++中判断某一文件或目录是否存在
    Eclipse快捷键大全(转载)
    关于注册模型失败的分析
    框架Model注册失败
    nop中导航属性的写法
    CodeFirst中导航属性的代码实现 理解
    MVC下验证码
    Androidi学习笔记 1
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/2886476.html
Copyright © 2020-2023  润新知