GOTO语句可以无条件跳到一个标签处

  • 格式:doc
  • 大小:38.50 KB
  • 文档页数:9

BEGIN...IF credit_rating < 3 THEN...EXIT; -- not allowedEND IF;END;记住,EXIT语句必须放在循环内。

如果想在PL/SQL块正常到达程序结尾之前而终止执行,可以使用RETURN语句。

EXIT-WHENEXIT-WHEN语句可以根据给定的条件跳出循环。

当遇到EXIT语句时,WHEN子句中的表达式值就会被计算。

如果条件满足,循环就会被终止,控制权转到循环语句之后的语句。

示例如下:LOOPFETCH c1INTO ...EXIT WHEN c1%NOTFOUND; -- exit loop if condition is true...END LOOP;CLOSE c1;在条件满足之前,循环是不会结束的。

所以,循环里的语句必须要改变循环条件的值。

上例中,如果FETCH语句返回了一行值,WNEN子句中的条件就为假;如果不能返回结果,WNEN 子句中的条件就为真,循环就会结束,控制权转入CLOSE语句。

EXIT-WHEN语句可以替代简单的IF语句,例如,比较下面两段代码:EXIT WHEN count > 100;这两个语句在逻辑上是等价的,但EXIT-WHEN语句更容易阅读和理解。

循环标签跟PL/SQL块一样,循环也是可以添加标签。

标签必须出现在LOOP语句的开端,语法如下:<<label_name>>LOOPsequence_of_statementsEND LOOP;而在LOOP语句结束部分出现的标签名称是可选的,语法如下:<<my_loop>>LOOP...END LOOP my_loop;在LOOP结束部分使用标签名称能够改善可读性。

无论使用哪种EXIT语句形式,都可以结束一个封闭的LOOP块,而不仅仅局限于当前的LOOP 块。

只要在我们想结束的封闭LOOP块上添加一个标签,然后像下面这样在EXIT语句中使用这个标签就可以了:<<outer>>LOOP...LOOP...EXIT outer WHEN ... -- exit both loopsEND LOOP;...END LOOP outer;2、WHILE-LOOPWHILE condition LOOPsequence_of_statementsEND LOOP;每次循环之前,程序都是计算布尔表达式的值。

如果条件为真,语句序列就会被执行,然后重新返回循环顶部计算布尔表达式的值;如果布尔表达式的值为假或空,控制权就会被交给循环之后的语句。

下面看一个例子:WHILE total <= 25000 LOOP...SELECT salINTO salaryFROM empWHERE x = x; ...total := total + salary;END LOOP;循环的次数是与条件相关的,而且在循环结束之前是未知的。

由于条件是在循环顶部测试的,所以语句序列有可能一次都没有执行。

在上面的例子中,如果total的初始值比25000大,那么条件值就是假,循环就会被跳过。

有些语言有LOOP UNTIL或是REPEAT UNTIL这样的结构,在底部测试条件表达式的值。

这样,语句序列就会至少执行一次。

PL/SQL没有这样的结构,但我们可以变通地使用下面的方法来实现这样的功能:要保证WHILE循环至少执行一次,在条件表达式中使用初始化过的布尔变量,如下例所示:done := FALSE;WHILE NOT done LOOPsequence_of_statements;done := boolean_expression;END LOOP;在循环内的语句必须为布尔变量赋上一个新值。

否则循环就会无限地执行下去。

如下例的两个LOOP语句在逻辑上是等价的:WHILE TRUE LOOP...END LOOP;LOOP...END LOOP;3、FOR-LOOPFOR语句会在指定的整数范围内进行循环操作。

循环的内容被关键字FOR和LOOP封闭起来。

两个"点"(..)作为范围操作符来使用。

语法如下:FOR counter IN [REVERSE] lower_bound..higher_bound LOOPsequence_of_statementsEND LOOP;当首次进入FOR循环时,循环的范围就会被确定下来,并且不会重新计算。

如下例所示,语句序列会执行三次,每执行一次,循环因子就会增加1。

下例演示了如果下界值等于上界值,循环中的语句序列只执行一次:FOR i IN 3 .. 3 LOOP -- assign the values 3 to isequence_of_statements -- executes one timeEND LOOP;默认情况下,循环总是从下界到上界。

不过也可以使用REVERSE关键字,让循环从上界往下界执行。

但是要记住,范围的书写格式仍旧是递增顺序的。

FOR i IN REVERSE 1 .. 3 LOOP -- assign the values 3,2,1 to isequence_of_statements -- executes three timesEND LOOP;FOR循环里,循环计数器只能当作常量来引用且不能为它赋值,如下例:FOR ctr IN 1 .. 10 LOOPIF NOT finished THENINSERT INTO ...VALUES (ctr); -- legalfactor := ctr * 2; -- legalELSEctr := 10; -- not allowedEND IF;END LOOP;迭代法循环范围的边界可以是文字、变量或表达式,但它们都必须是数字。

否则PL/SQL会抛出预定义异常VALUE_ERROR。

如下例,下界不一定非得是1。

但循环计数器只能是每次增加1。

j IN -5 .. 5k IN REVERSE ststep IN 0..TRUNC(high/low) * 2在PL/SQL内部,它会把边界值赋给一个临时的PLS_INTEGER变量,并在需要的时候把值转换成最接近的整数。

PLS_INTEGER的范围是-2**31到2**31之间。

所以,如果边界值超过这个范围,我们就会得到一个数字溢出错误:DECLAREhi NUMBER := 2 ** 32;BEGINFOR j IN 1 .. hi LOOP -- causes a 鈥檔umeric overflow鈥?error...END LOOP;END;有些语言提供了STEP子句,它能让我们指定循环增量。

PL/SQL没有这样的结构,但我们可以在FOR循环内扩大循环计数器的倍数来实现这样的功能。

在下面的例子中,我们今天的日期赋给索引表的第一个、第五个和第十五个元素。

动态范围PL/SQL允许我们在运行时决定循环的范围,如下例所示:SELECT COUNT(empno)INTO emp_countFROM emp;FOR i IN 1 .. emp_count LOOP...END LOOP;emp_count在运行时是未知的;SELECT语句在运行时才返回结果值。

如果循环范围中的下界值超过上界值会怎样呢?如下例所示,循环内的语句序列就不会被执行,控制权直接交给下一个语句:-- limit becomes 1FOR i IN 2 .. LIMIT LOOPsequence_of_statements -- executes zero timesEND LOOP;-- control passes here作用域规则循环计数器只在循环内部定义,我们不能在循环外引用它。

循环退出后,循环计数器就会失效,如下例:FOR ctr IN 1 .. 10 LOOP...END LOOP;sum := ctr - 1; -- not allowed我们不需要显式声明循环计数器,因为它会被隐式地声明为INTEGER类型本地变量。

下面的例子中本地声明覆盖了全局声明:如果想在上例中引用全局变量,我们就得借助标签和点标志,例如:<<main>>DECLAREctr INTEGER;...BEGIN...FOR ctr IN 1 .. 25 LOOP...IF main.ctr > 10 THEN -- refers to global variable...END IF;END LOOP;END main;同样的作用域规则也适用于嵌套FOR循环。

如下面的例子,两个循环计数器的名字相同,所以,用从内层循环引用外层循环的循环计数器,就必须使用标签和点标志:<<outer>>FOR step IN 1 .. 25 LOOPFOR step IN 1 .. 10 LOOP...IF outer.step > 15 THEN ...END LOOP;END LOOP outer;使用EXIT语句EXIT语句可以立即结束一个FOR循环。

例如,下面的循环语句正常情况应该执行十次,但是,如果FETCH语句取得数据失败,循环就会立即终止,无论它执行过多少次:在使用EXIT时,我们可以结束任何封闭循环,而不仅仅是当前循环。

只要在我们想结束的封闭循环上加上标签,然后在EXIT语句中引用它,就能结束做过标记的FOR循环了,如下例:<<outer>>FOR i IN 1 .. 5 LOOP...FOR j IN 1 .. 10 LOOPFETCH c1 INTO emp_rec;EXIT outer WHEN c1%NOTFOUND; -- exit both FOR loopsEND LOOP;END LOOP outer;-- control passes here四、顺序控制:GOTO和NULL语句与IF和LOOP语句不通,GOTO和NULL语句对PL/SQL编程来说不是必须的。

PL/SQL结构中很少用到GOTO语句。

有时,它就是用于简化逻辑的。

NULL用于改善可读性使条件语句看起来更加清晰。

滥用GOTO能使结构混乱,不易理解和维护(有时被称为意大利面条式代码- spaghetti code)。

所以,GOTO语句的使用一定要有节制。

例如,要从一个深嵌套中跳到异常控制块,要用异常抛出而不是使用GOTO语句。

GOTO语句可以无条件跳到一个标签处。

标签名称在它所处的作用范围内必须是唯一的。

执行的时候,GOTO语句会把控制权交给一个做了标记的语句或块。

GOTO语句可以向上或向下跳转,示例如下:BEGIN...GOTO insert_row;...<<insert_row>>INSERT INTO emp VALUES ...END;再看一个向上跳转的例子:BEGIN...<<update_row>>BEGINUPDATE emp SET ......END;...GOTO update_row;...下例中的标签end_loop是不允许的,因为它并没有到达一个处理语句:DECLAREdone BOOLEAN;BEGIN...FOR i IN 1 .. 50 LOOPIF done THENGOTO end_loop;END IF;...<<end_loop>> -- not allowedEND LOOP; -- not an executable statementEND;。