Oracle数据库之PL/SQL流程控制语句

 

Oracle数据库之PL/SQL流程控制语句

在任何计算机编程语言(如C,Java,C#等)都有各种流程控制语句,同样,在PL/SQL中也存在这样的流程控制结构。

几种常见的流程控制结构:

struct

一、条件结构

1. 简单IF结构

-- 简单IF结构
IF <布尔表达式> THEN
    满足条件时执行的语句
END IF;

2. IF-ELSE结构

-- IF-ELSE结构
IF <布尔表达式> THEN
    满足条件时执行的语句
ELSE
    不满足条件时执行的语句
END IF;

3. 多重IF

复制代码
-- 多重IF
IF <布尔表达式1> THEN
    满足条件1时执行的语句
ELSIF <布尔表达式2> THEN
    满足条件2时执行的语句
ELSIF <布尔表达式3> THEN
    满足条件3时执行的语句
ELSE
    满足条件1、2、3均不满足时执行的语句
END IF;
复制代码

注意:ELSIF不能写成ELSEIF

示例:

复制代码
DECLARE
    emp_id  employee.id%TYPE := &empid;
    emp_salary employee.salary%TYPE;
    info VARCHAR2(50);
BEGIN
    SELECT salary INTO emp_salary FROM employee WHERE id = emp_id;
    /* 根据薪资情况判断 */
    IF emp_salary < 1500 THEN
        info := '太少了,不加就辞职!';
    ELSIF emp_salary <3000 THEN
        info := '还将就,先干着吧!';
    ELSE
        info := '目前还比较满意,以后再看!';
    END IF;
    DBMS_OUTPUT.PUT_LINE(info);
    EXCEPTION
        WHEN no_data_found THEN
            DBMS_OUTPUT.PUT_LINE('没有数据~!');
        WHEN others THEN
            DBMS_OUTPUT.PUT_LINE(sqlcode || '---' || sqlerrm);        
END;
复制代码

4. CASE

语法一:

复制代码
CASE 条件表达式
    WHEN 条件表达式结果1 THEN 
        语句1
    WHEN 条件表达式结果2 THEN
        语句2
    ......
    WHEN 条件表达式结果n THEN
        语句n
  [ELSE 条件表达式结果]
END CASE;
复制代码

示例:

复制代码
DECLARE
  grade CHAR(1);
BEGIN
  grade := '&g';

  CASE grade
    WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
    WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
    WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
    WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
    WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
    ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
  END CASE;
END;
复制代码

语法二:

复制代码
CASE 
  WHEN 条件表达式1 THEN
     语句1
  WHEN 条件表达式2 THEN
     语句2
  ......
  WHEN 条件表达式n THEN 
     语句n
  [ELSE 语句]
END CASE;
复制代码

示例:

复制代码
DECLARE
  grade CHAR(1);
BEGIN
  grade := '&g';

  CASE
    WHEN grade = 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
    WHEN grade = 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
    WHEN grade = 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
    WHEN grade = 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
    WHEN grade = 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
    ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
  END CASE;
END;
复制代码

二、循环结构

1. 简单循环

语法:

LOOP
    循环体语句;
    [EXIT WHEN <条件语句>]
END LOOP;

示例1:

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

示例2:

复制代码
DECLARE
  x NUMBER := 0;
BEGIN
  LOOP
    DBMS_OUTPUT.PUT_LINE ('循环中: x = ' || TO_CHAR(x));
    x := x + 1;
    IF x > 3 THEN
      EXIT;
    END IF;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE(' 循环结束:  x = ' || TO_CHAR(x));
END;
复制代码

2. WHILE循环

语法:

WHILE <布尔表达式> LOOP
    循环体语句;
END LOOP;

示例1:

复制代码
DECLARE
  done  BOOLEAN := FALSE;
BEGIN
  WHILE done LOOP
    DBMS_OUTPUT.PUT_LINE ('Oh, no! It's wrong!');
    done := TRUE;
  END LOOP;

  WHILE NOT done LOOP
    DBMS_OUTPUT.PUT_LINE ('Hello, world!');
    done := TRUE;
  END LOOP;
END;
复制代码

3. FOR循环

语法:

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

说明:

使用关键字REVERSE,循环变量自动减1。跟在IN REVERSE后面的数字应是从小到大的顺序,而且必须是整数,不能是变量或表达式。

示例1:

复制代码
BEGIN
  DBMS_OUTPUT.PUT_LINE ('下限 < 上限:');

  FOR i IN 1..3 LOOP
    DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;

  DBMS_OUTPUT.PUT_LINE ('下限 = 上限:');

  FOR i IN 2..2 LOOP
    DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;

  DBMS_OUTPUT.PUT_LINE ('下限 > 上限:');

  FOR i IN 3..1 LOOP
    DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;
END;
复制代码

输出结果:

复制代码
下限 < 上限:
1
2
3
下限 = 上限:
2
下限 > 上限:
复制代码

示例2:

复制代码
BEGIN
  DBMS_OUTPUT.PUT_LINE ('反转 -- 下限 < 上限:');

  FOR i IN REVERSE 1..3 LOOP
    DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;

  DBMS_OUTPUT.PUT_LINE ('反转 -- 下限 = 上限:');

  FOR i IN REVERSE 2..2 LOOP
    DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;

  DBMS_OUTPUT.PUT_LINE ('反转 -- 下限 > 上限:');

  FOR i IN REVERSE 3..1 LOOP
    DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;
END;
复制代码

运行结果:

复制代码
反转 -- 下限 < 上限:
3
2
1
反转 -- 下限 = 上限:
2
反转 -- 下限 > 上限:
复制代码

循环结构中,均可以在适当的时候构建条件使用EXIT退出循环结构。

三、顺序结构

1. GOTO

GOTO语句用于跳转到指定<<标号>>去执行语句,是无条件跳转到指定的标号去的意思。

注意:标号是用<< >>括起来的标识符。

语法:

GOTO label;

GOTO语句缺点是会增加程序的复杂性,降低可读性,所以Oracle建议不要使用。

示例:

复制代码
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;
复制代码

2. NULL

空语句,执行没有任何实际效果,可以使某些语句变得有意义,提高程序的可读性,保证其他语句结构的完整性和正确性,通常用于占位置。

示例1:

复制代码
DECLARE
  valid BOOLEAN := TRUE;
BEGIN
  GOTO update_row;

  IF valid THEN
  <<update_row>>
    NULL;
  END IF;
END;
复制代码

示例2:

复制代码
DECLARE
  v_job_id  VARCHAR2(10);
   v_emp_id  NUMBER(6) := 110;
BEGIN
  SELECT job_id INTO v_job_id
  FROM employees
  WHERE employee_id = v_emp_id;

  IF v_job_id = 'SA_REP' THEN
    UPDATE employees
    SET commission_pct = commission_pct * 1.2;
  ELSE
    NULL;
  END IF;
END;
复制代码

 

posted @ 2021-07-28 20:43  Janus2003  阅读(202)  评论(0编辑  收藏  举报