[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

简介:

介绍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( 12 OF   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 ;

 


本文转自yonghu86 51CTO博客,原文链接:http://blog.51cto.com/yonghu/1321352,如需转载请自行联系原作者

相关文章
|
22天前
|
SQL Perl
PL/SQL经典练习
PL/SQL经典练习
13 0
|
22天前
|
SQL Perl
PL/SQL编程基本概念
PL/SQL编程基本概念
12 0
|
27天前
|
SQL Perl
PL/SQL Developer 注册机+汉化包+用户指南
PL/SQL Developer 注册机+汉化包+用户指南
15 0
|
3月前
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
83 0
|
26天前
|
SQL Go
SQL编程
SQL编程
8 0
|
1月前
|
SQL 关系型数据库 MySQL
[MySQL]SQL优化之索引的使用规则
[MySQL]SQL优化之索引的使用规则
|
1月前
|
SQL Oracle 关系型数据库
Oracle系列十一:PL/SQL
Oracle系列十一:PL/SQL
|
1月前
|
SQL Oracle 关系型数据库
Oracle系列之八:SQL查询
Oracle系列之八:SQL查询
|
3月前
|
SQL 存储 Oracle
oracle如何定期备份数据库sql文件
【1月更文挑战第7天】oracle如何定期备份数据库sql文件
58 8
|
5天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
40 10

推荐镜像

更多