PL/SQL(四)条件控制和循环控制

PL/SQL程序可通过条件或循环结构来控制命令执行的流程。PL/SQL提供了丰富的流程控制语句,与C#一样也有三种控制结构:

顺序结构 条件结构 循环结构

条件控制

C#中的条件控制使用关键字if和switch。PL/SQL中关于条件控制的关键字有IF-THEN、IF-THEN-ELSE、IF-THEN-ELSIF和多分枝条件CASE。

★IF-THEN

该结构先判断一个条件是否为TRUE,条件成立则执行对应的语句块,与C#中的if语句很相似,具体语法是:

C#中if语法 PL/SQL中IF语法

  if (条件){

    //条件结构体

  }

  IF 条件 THEN

    --条件结构体

  END IF;

说明:

① 用IF关键字开始,END IF关键字结束,注意END IF后面有一个分号。
② 条件部分可以不使用括号,但是必须以关键字THEN来标识条件结束,如果条件成立,则执行THEN后到对应END IF之间的语句块内容。如果条件不成立,则不执行条件语句块的内容。
③ C#结构用一对大括号来包含条件结构体的内容。PL/SQL中关键字THEN到END IF之间的内容是条件结构体内容。
④ 条件可以使用关系运算符和逻辑运算符。

案例1:查询JAMES的工资,如果大于900元,则发奖金800元。

代码演示:IF-THEN应用

DECLARE 
  newSal emp.sal % TYPE; 
BEGIN 
  SELECT sal INTO newSal FROM emp WHERE ename='JAMES'; 
  IF newSal>900 THEN ①
    UPDATE emp SET comm=800 WHERE ename='JAMES'; 
  END IF; 
  COMMIT ; ② 
END;

 

代码解析:

① 先判断条件,如果条件为TRUE,则执行条件结构体内部的内容。
② 在PL/SQL块中可以使用事务控制语句,该COMMIT同时也能把PL/SQL块外没有提交的数据一并提交,使用时需要注意。

★IF-THEN-ELSE

语法格式:IF-THEN-ELSE

C#中if语法 PL/SQL中IF语法

 if (条件){

  //条件成立结构体

 } else{

  //条件不成立结构体

 }

 IF 条件 THEN

  --条件成立结构体

 ELSE

  --条件不成立结构体

 END IF;

语法解析:

把ELSE与IF-THEN连在一起使用,如果IF条件不成立则执行就会执行ELSE部分的语句。

案例2:查询JAMES的工资,如果大于900元,则发奖金800元,否则发奖金400元。

代码演示:IF-THEN-ELSE应用

DECLARE 
  newSal emp.sal % TYPE; 
BEGIN 
  SELECT sal INTO newSal FROM emp WHERE ename='JAMES'; 
  IF newSal>900 THEN 
    UPDATE emp SET comm=800 WHERE ename='JAMES'; 
  ELSE 
    UPDATE emp SET comm=400 WHERE ename='JAMES'; 
  END IF; 
END;

 IF-THEN-ELSIF

C#中if语法 PL/SQL中IF语法

if (条件2){

  //条件成立结构体

}

else if(条件2){

  //条件不成立结构体

}

else{

  //以上条件都不成立结构体

}

IF 条件1 THEN

  --条件1成立结构体

ELSIF 条件2 THEN

  --条件2成立结构体

ELSE

  --以上条件都不成立结构体

END IF;

语法解析:

PL/SQL中的再次条件判断中使用关键字ELSIF,而C#使用else if。

案例3:查询JAMES的工资,如果大于1500元,则发放奖金100元,如果工作大于900元,则发奖金800元,否则发奖金400元。

代码演示:IF-THEN-ELSIF应用

DECLARE 
  newSal emp.sal % TYPE; 
BEGIN 
  SELECT sal INTO newSal FROM emp WHERE ename='JAMES'; 
  IF newSal>1500 THEN 
    UPDATE emp SET comm=1000 WHERE ename='JAMES'; 
  ELSIF newSal>1500 THEN 
    UPDATE emp SET comm=800 WHERE ename='JAMES'; 
  ELSE 
    UPDATE emp SET comm=400 WHERE ename='JAMES';   END IF; END;

 

CASE

CASE是一种选择结构的控制语句,可以根据条件从多个执行分支中选择相应的执行动作。也可以作为表达式使用,返回一个值。类似于C#中的switch语句。语法是:

语法格式:CASE


CASE [selector]

  WHEN 表达式1 THEN 语句序列1;

  WHEN 表达式2 THEN 语句序列2;

  WHEN 表达式3 THEN 语句序列3;

  ……

  [ELSE 语句序列N];

END CASE;


 

语法解析:

如果存在选择器selector,选择器selector与WHEN后面的表达式匹配,匹配成功就执行THEN后面的语句。如果所有表达式都与selector不匹配,则执行ELSE后面的语句。

案例4:输入一个字母A、B、C分别输出对应的级别信息。

代码演示:CASE中存在selector,不返回值

DECLARE 
  v_grade CHAR(1):=UPPER('&p_grade'); ① 
BEGIN 
  CASE v_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'); 
    ELSE 
      dbms_output.put_line('No such grade'); 
  END CASE; 
END;

代码解析:
① & grade表示在运行时由键盘输入字符串到grade变量中。
② v_grade分别于WHEN后面的值匹配,如果成功就执行WHEN后的程序序列。


CASE语句还可以作为表达式使用,返回一个值。

代码演示:CASE中存在selector,作为表达式使用

DECLARE 
  v_grade CHAR(1):=UPPER('&grade'); 
  p_grade VARCHAR(20) ; 
BEGIN 
p_grade := ①   CASE v_grade
    WHEN 'A' THEN       'Excellent'
    WHEN 'B' THEN       'Very Good'     WHEN 'C' THEN       'Good'     ELSE       'No such grade'
  END;   bms_output.put_line('Grade:' ||v_grade||',the result is '||p_grade); END;

 

代码解析:

① CASE语句可以返回一个结果给变量p_grade


PL/SQL还提供了搜索CASE语句。也就是说,不使用CASE中的选择器,直接在WHEN后面判断条件,第一个条件为真时,执行对应THEN后面的语句序列。

代码演示:搜索CASE

DECLARE 
  v_grade CHAR(1):=UPPER('&grade'); 
  p_grade VARCHAR(20) ; 
BEGIN 
  p_grade := 
    CASE 
      WHEN v_grade='A' THEN 
        'Excellent' 
      WHEN v_grade='B' THEN 
        'Very Good' 
      WHEN v_grade='C' THEN 
        'Good' 
      ELSE 
        'No such grade' 
    END; 
    dbms_output.put_line('Grade:' ||v_grade||',the result is '||p_grade); 
END;

 

※循环结构

PL/SQL提供了丰富的循环结构来重复执行一些列语句。Oracle提供的循环类型有:
1. 无条件循环LOOP-END LOOP语句
2. WHILE循环语句
3. FOR循环语句
在上面的三类循环中EXIT用来强制结束循环,相当于C#循环中的break。

LOOP循环

LOOP循环是最简单的循环,也称为无限循环,LOOP和END LOOP是关键字。

语法格式:LOOP循环


 

LOOP

  --循环体

END LOOP;


 

语法格式:

1. 循环体在LOOP和END LOOP之间,在每个LOOP循环体中,首先执行循环体中的语句序列,执行完后再重新开始执行。
2. 在LOOP循环中可以使用EXIT或者[EXIT WHEN 条件]的形式终止循环。否则该循环就是死循环。

案例5:执行1+2+3+…+100的值

代码演示:LOOP循环

DECLARE 
  counter number(3):=0; 
  sumResult number:=0; 
BEGIN 
  LOOP 
    counter := counter+1; 
    sumResult := sumResult+counter; 
    IF counter>=100 THEN ① 
      EXIT; 
    END IF; 
    -- EXIT WHEN counter>=100; ② 
  END LOOP; 
  dbms_output.put_line('result is :'||to_char(sumResult)); 
END;

 

代码解析:

① LOOP循环中可以使用IF结构嵌套EXIT关键字退出循环
② 注释行,该行可以代替①中的循环结构,WHEN后面的条件成立时跳出循环。

★WHILE循环

与C#中的while循环很类似。先判断条件,条件成立再执行循环体。

语法格式:WHILE

C#中while语法 PL/SQL中WHILE语法

 while (条件){

  //循环体体

 }

 WHILE 条件 LOOP

  --循环体

 END LOOP;

案例6:WHILE循环

代码演示:WHILE循环

DECLARE
    counter number(3):=0;
    sumResult number:=0;
BEGIN
    WHILE counter<100 LOOP
        counter:=counter+1;
        sumResult:=sumResult+counter;
    END LOOP;
        dbms_output.put_line('result is :'||sumResult);
END

 

★FOR循环

FOR循环需要预先确定的循环次数,可通过给循环变量指定下限和上限来确定循环运行的次数,然后循环变量在每次循环中递增(或者递减)。FOR循环的语法是:

语法格式:FOR循环


 

FOR 循环变量 IN [REVERSE] 循环下限..循环上限 LOOP LOOP --循环体 END LOOP;


 

语法解析:

循环变量:该变量的值每次循环根据上下限的REVERSE关键字进行加1或者减1。

REVERSE:指明循环从上限向下限依次循环。

案例7:FOR循环

代码演示:FOR循环

DECLARE
    counter number(3):=0;
    sumResult number:=0:
BEGIN
    FOR counter IN 1..100 LOOP
        sumResult := sumResult+counter;
    END LOOP;
    dbms_output.put_line('result is :'||sumResult);
END;

 

※顺序结构

在程序顺序结构中有两个特殊的语句。GOTO和NULL

★GOTO语句

GOTO语句将无条件的跳转到标签指定的语句去执行。标签是用双尖括号括起来的标示符,在PL/SQL块中必须具有唯一的名称,标签后必须紧跟可执行语句或者PL/SQL块。GOTO不能跳转到IF语句、CASE语句、LOOP语句、或者子块中。

★NULL语句

NULL语句什么都不做,只是将控制权转到下一行语句。NULL语句是可执行语句。NULL语句在IF或者其他语句语法要求至少需要一条可执行语句,但又不需要具体操作的地方。比如GOTO的目标地方不需要执行任何语句时。

案例8:GOGO 和 NULL

代码演示:GOTO和NULL

DECLARE
    sumsal emp.sal@TYPE;
BEGIN
    SELECT SUM(sal) INTO sumal FROM EMP;
    IF sumsal>20000 THEN
        GOTO first_label;①
    ELSE
        GOTO second_label;②
    END IF;
    <<first_label>>③
    dbms_output.put_line('ABOVE 20000:'||sumsal);
    <<second_label>>NULL;
END;

 

代码解析:

① 跳转到程序first_label位置,就是②的位置,first_label是一个标签,用两个尖括号包含。
② 无条件跳转到sedond_label位置,就是④的位置。④处不执行任何内容,因此是一个NULL语句。


与C#一样,在PL/SQL中,各种循环之间可以相互嵌套。

 

posted @ 2016-11-18 16:51  冯瑞  阅读(2207)  评论(0编辑  收藏  举报