oracle外层循环和内层循环,Oracle学习之三 程序控制结构

1.条件控制

1.1 IF语句

if语句由于根据条件,执行两个代码块之一。其语法形式如下:

IF 条件1 THEN。。。 ELSEIF 条件2THEN。。。ELSE。。。END IF;

这里,elseif和else块时可选的。当使用条件分支语句时,不仅可以使用if语句进行简单条件判断,而且还可以使用if语句进行二重分支和多重分支判断。

1.2 CASE语句和CASE表达式

使用CASE语句处理多重条件分支有两种方法:使用单一选择符进行等值比较;使用多种条件进行非等值比较。

1) 在CASE语句中使用单一选择符进行等值比较

当使用CASE语句进行多重条件分支时,如果条件选择符完全相同,并且条件表达式为相同条件选择,那么可以选择使用单一选择符进行等值比较。

CASEselectorWHEN exp1 THENstate1;WHEN exp2 THENstate2; ....[else stateN;] END CASE;

这里,selector用于指定条件选择符,exp用于指定条件值的表达式,state用于指定要执行的条件操作。如果设置的所有条件都不满足,就会执行else语句,为避免CASE_NOT_FOUND异常,在编写CASE语句时应该带有else子句。

2) 在CASE语句中使用多种条件比较

如果包含有多种条件进行不等比较,那么必须在WHEN子句中指定比较条件。

CASEWHEN condition1 THENstate1;WHEN condition2 THENstate2; ....[else stateN;] END CASE;

condition用于指定不同的比较条件。

3) CASE表达式

CASE表达式也可以采用上面两种形式。

case_experssion := CASE exp  WHEN。。。

或者

case_experssion := CASE  WHEN。。。

2.循环控制

2.1 基本循环

基本循环语句以LOOP开始,END LOOP 结束。

LOOP statement; ...EXIT [WHEN condition];END LOOP;

当使用基本循环时,无论是否满足条件,语句至少会执行一次。当条件为true时,会退出循环,并执行end LOOP后的相应操作。注意,当编写基本循环时,一定要包含exit语句,否则PL/SQL块会陷入死循环;另外还应该定义循环控制变量,并且在循环体内修改循环控制的值。

2.2 WHILE循环

只有条件为true时,才执行循环体内的内容,while循环以while…LOOP 开始,以end  LOOP结束。

2.3 FOR循环

当使用基本循环或者while循环时,需要定义循环控制变量,并且循环控制变量不仅可以是NUMBER类型,也可以使用其他数据类型;而当使用for循环时,会隐含定义循环控制变量

FOR counter IN [REVERSE]lower_bound ..upper_bound LOOP statement; ...end loop;

counter是循环控制变量,该变量由Oracle隐含定义,不需要显式定义;lower_bound和upper_bound分别对应于循环控制变量的上下界值。默认情况下,当使用FOR循环时,每次循环时循环控制变量会自动加1,如果指定了reverse选项,则每次循环控制变量自动减1.

2.4嵌套循环和标号

嵌套循环是指在一个循环语句中嵌入另一个循环语句,而标号(Lable)则用于标记嵌套块或者嵌套循环。通过在嵌套循环中使用标号,可以区分内层和外层循环,并且可以在内层循环中直接退出外层循环。可以使用<>定义标号。

3.顺序控制

PL/SQL不仅提供了条件分支语句和循环控制语句,还提供了顺序控制语句GOTO和NULL。但是,在一般情况下尽量不要使用goto和null语句。

3.1 GOTO语句

GOTO语句用于跳转到指定标号处去执行语句。注意,因为使用GOTO语句会增加程序的复杂性,并且使得应用程序可读性变差,所以开发应用程序时,一般不建议使用GOTO语句。

其语法形式为:

GOTO label_name;

其中,label_name是已经定义的标号名,需要注意的是,标号后至少要包含一条可执行语句。

3.2 NULL语句

NULL语句不会执行任何操作,并且会直接将控制传递到下一条语句。使用NULL语句的好处时可以提高程序的可读性。

4.异常处理

PL/SQL语言中,任何类型的错误将被看作为不应该在程序中发生的异常情况。异常可以是以下之一:

☆ 由系统产生的错误(例如内存不足,重复索引值)

☆ 由用户行为导致的错误

☆ 由应用程序发出给用户的警告

PL/SQL使用一种异常处理器来捕获和响应这些错误。当发生错误时,不管是系统错误还是应用程序错误都会抛出一个异常。此时,当前PL/SQL块执行部分的处理就会中止,程序流程就会转到当前块的异常处理部分来处理异常。在完成异常处理后,程序不能返回到执行部分。

通常,异常分为两种类型:系统异常和程序员自定义的异常。

1) 系统异常

系统异常时由Oracle自己定义的,通常时由PL/SQL运行时引擎在检测了错误时抛出的。

系统异常不需要我们定义,在应用程序运行时会自动抛出,然后交给我们编写异常处理部分进行异常处理。

表4-1 Oracle预定义异常

异常名

对应错误号

说明

ACCESS_INTO_NULL

ORA-06530

当开发对象类型应用时,在引用对象属性之前,必须先初始化对象。如果没有初始化,直接为对象属性赋值则会抛出异常。

CASE_NOT_FOUND

ORA-06592

在CASE语句中,WHEN子句中没有包含必须的条件分支,且没有ELSE语句。

COLLECTION_IS_NULL

ORA-06531

在给集合元素赋值前,必须首先初始化集合元素。

CURSOR_ALREADY_OPEN

ORA-06511

当重新打开已经打开的游标时抛出异常

DUP_VAL_INDEX

ORA-00001

在唯一索引对应的列上键入重复值时抛出异常

INVALID_CURSOR

ORA-01001

当试图在不合法的游标上执行操作时抛出

INVALID_NULBER

ORA-01722

当内嵌sql语句不能呢个有效地将字符转换为数字时抛出

NO_DATA_FOUND

ORA-01403

当执行select into 未返回行,或者引用了索引表未初始化元素时抛出

TOO_MANY_ROWS

ORA-01422

当执行select into 语句时,如果返回超过一行抛出

ZERO_DIVIDE

ORA-01476

除数为0时抛出

SUBSCRIPT-BEYOND-COUNT

ORA-06533

当使用嵌套表或者VARRAY元素时,如果元素下标超过了范围则抛出

SUBSCRIPT_OUTSIDE_LIMIT

ORA-06532

当使用嵌套表或者VARRAY元素时,如果元素下标为负数抛出

VALUE_ERROR

ORA-06502

执行赋值操作时,如果变量长度不足以容纳实际数据时抛出

LOGIN_BENIED

ORA-01017

应用程序需要连接到Oracle数据库时,如果提供了错误的用户名或口令时抛出

NOT_LOGGED_ON

ORA-01012

如果应用程序没有连接到Oracle数据库时抛出

PROGRAM_ERROR

ORA-06501

如果出现该错误说明PL/SQL内部存在问题,可能需要重装数据字典

ROWTYPE_MISMATCH

ORA-06504

当执行赋值操作时,如果宿主游标变量和PL/SQL游标变量的返回类型不兼容时抛出

SELF_IS_NULL

ORA-30625

当使用对象类型时,如果在NULL实例上调用成员方法时抛出

STORAGE_ERROR

ORA-06500

如果超出内存空间或者内存被损坏时抛出

SYS_INVALID_ROWID

ORA-01410

将字符串转换为rowid时,必须使用有效的字符串,否则抛出异常

TIMEOUT_ON_RESOURCE

ORA-00051

如果Oracle等待资源时出现超时错误时抛出

2)自定义异常

异常处理的流程包括定义异常、抛出异常和处理异常三个部分。

4.1 定义异常

在异常被抛出或处理之前,必须先定义。系统异常已经由Oracle本身定义了,因此我们在应用程序中不需要定义它们。我们可以使用两种不同的方式来自定义异常。

① 定义命名的异常

为了处理异常,必须对有一个该异常的名称。通过在EXCEPTION关键字前列出我们想在程序中抛出的异常的名称,就可以定义一个异常。

异常的名称只能以两种方式被引用:

☆ 在要跑出异常的程序执行部分用RAISE语句引用

☆  在要处理抛出的异常的异常处理部分的WHEN子句中引用。

②将异常名称与错误号关联

EXCEPTION_INIT命令用于将一个内部错误号与异常的名称关联。关联完成后,就可以通过名称抛出异常,并编写一个显式的WHEN处理器捕获异常。

EXCEPTION_INIT必须出现在块的定义部分,并且异常的名字必须在相同的块或者包规范中已经定义了。

DECLARE 异常名称 EXCEPTION; PRAGMA EXCEPTION_INIT(异常名称,错误号);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值