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

[推荐]ORACLE PL/SQL编程详解之三:

PL/SQL流程控制语句(不给规则,不成方圆)

——通过知识共享树立个人品牌。

继上五篇:

[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)

[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)

ORACLE PL/SQL编程之八:把触发器说透

接下来再次介绍PL/SQL的基础篇:PL/SQL流程控制语句,还望大家继续支持与推荐~!


本篇主要内容如下:

3.1  条件语句

3.2  CASE 表达式

3.3  循环

3.4  标号和GOTO

3.5  NULL 语句


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

l 控制语句: IF 语句

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

l 顺序语句: 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/SQL中GOTO语句是无条件跳转到指定的标号去的意思。语法如下:

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

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

u 跳转到非执行语句前面。

u 跳转到子块中。

u 跳转到循环语句中。

u 跳转到条件语句中。

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

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

例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;

© 2011  EricHu

原创作品,转贴请注明作者和出处,留此信息。

------------------------------------------------

cnBlobs:http://www.cnblogs.com/huyong/CSDN:http://blog.csdn.net/chinahuyong

作者:EricHu(DB、C\S、B\S、WebService、WCF、PM等)
出处:http://www.cnblogs.com/huyong/

Q Q:80368704   E-Mail: 80368704@qq.com
本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。
更多文章请看 [置顶]索引贴——(不断更新中)

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

  1. [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)

    原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...

  2. 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航

    原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...

  3. [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)

    原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...

  4. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  5. [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

    原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日 ...

  6. ORACLE PL/SQL编程详解(转)

    原帖地址:http://blog.csdn.net/chenjinping123/article/details/8737604 ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语 ...

  7. 010-Hadoop Hive sql语法详解5-HiveQL与SQL区别

    1.Hive不支持等值连接 •SQL中对两表内联可以写成:•select * from dual a,dual b where a.key = b.key;•Hive中应为•select * from ...

  8. Oracle中dbms_random包详解

    Oracle之DBMS_RANDOM包详解参考自:https://www.cnblogs.com/ivictor/p/4476031.html https://www.cnblogs.com/shen ...

  9. Oracle的exp/imp详解

    原文地址:Oracle的exp/imp详解 作者:jxlazzw 备份概述 逻辑备份:备份可分为两类 ,物理备份和逻辑备份 物理备份:该方法实现数据库的完整恢复,但需要极大的外部存储设备,例如磁带库, ...

随机推荐

  1. Team Services and Team Foundation Server官方资料入口

    Team Foundation Server msdn 中文文档入口 Team Services or Team Foundation Server www.visualstudio.com 英文文档 ...

  2. 关闭 MsMpEng.exe

    MsMpEng.exe是Windows Defender 自动保护服务的核心引擎. 系统是win8.1 最近发现MsMpEng.exe是任务管理器里面最占内存的一个程序,且无法强制结束程序.偶然发现一 ...

  3. WPF学习(5)依赖属性

    今天我们来学习WPF一个比较重要的概念:依赖属性.这里推荐大家看看周永恒大哥的文章,讲的确实很不错.我理解的没那么深入,只能发表一下自己的浅见.提到依赖属性,不得不说我们经常使用的传统的.net属性, ...

  4. php脚本生成google play url的下载链接,下载apk并自动反编译后获取android版本号

        需求:     get the offer tracking link    follow the redirect to get google play url    Go to http: ...

  5. 【MySQL案件】ERROR 1665 (HY000)

    转载请注明: http://blog.csdn.net/jason_asia/article/details/36240815 1.1.1. ERROR 1665 (HY000) [环境的叙述性说明] ...

  6. Team Foundation Server 2015使用教程--默认团队checkin权限修改

  7. ASP.NET MVC(C#)和Quartz.Net组件

    ASP.NET MVC(C#)和Quartz.Net组件 在之前的文章<推荐一个简单.轻量.功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler>和&l ...

  8. Windows下一个SlikSVN使用

    我相信所有的应SVN不熟悉.使用过.可是并非人人都自己配置过SVNserver.以下就是我配置SVNserver的步骤.以及在配置过程中碰见的一些问题,在此记录,希望对你有所帮助. 安装 双击执行&q ...

  9. KMP算法(转)

    KMP算法 在介绍KMP算法之前,先介绍一下BF算法. 一.BF算法 BF算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串P的第一个字符进行匹配,若相等,则继续比较S的第二个 ...

  10. 怎么理解Condition(转)

    在java.util.concurrent包中,有两个很特殊的工具类,Condition和ReentrantLock,使用过的人都知道,ReentrantLock(重入锁)是jdk的concurren ...