📄 第四章 pl-sql的控制结构 - pl-sql用户指南与参考 - whatiswhat.htm
字号:
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>LOOP</STRONG><BR> ...<BR> <STRONG>IF</STRONG> credit_rating < 3 <STRONG>THEN</STRONG><BR> ...<BR> <STRONG>EXIT</STRONG>; <EM>-- exit loop immediately</EM><BR> <STRONG>END</STRONG> <STRONG>IF</STRONG>;<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;<BR><EM>-- control resumes here</EM>
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>下面再举一个不能在PL/SQL块中使用EXIT语句的例子: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>BEGIN</STRONG><BR> ...<BR> <STRONG>IF</STRONG> credit_rating < 3 <STRONG>THEN</STRONG><BR> ...<BR> <STRONG>EXIT</STRONG>; <EM>-- not allowed</EM><BR> <STRONG>END</STRONG> <STRONG>IF</STRONG>;<BR><STRONG>END</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>记住,EXIT语句必须放在循环内。如果想在PL/SQL块正常到达程序结尾之前而终止执行,可以使用RETURN语句。
</P>
<UL>
<LI>EXIT-WHEN </LI></UL>
<P>EXIT-WHEN语句可以根据给定的条件跳出循环。当遇到EXIT语句时,WHEN子句中的表达式值就会被计算。如果条件满足,循环就会被终止,控制权转到循环语句之后的语句。示例如下:
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>LOOP</STRONG><BR> <STRONG>FETCH</STRONG> c1<BR> <STRONG>INTO</STRONG> ...<BR><BR> <STRONG>EXIT</STRONG> <STRONG>WHEN</STRONG> c1%NOTFOUND; <EM>-- exit loop if condition is true</EM><BR> ...<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;<BR><BR><STRONG>CLOSE</STRONG> c1;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>在条件满足之前,循环是不会结束的。所以,循环里的语句必须要改变循环条件的值。上例中,如果FETCH语句返回了一行值,WNEN子句中的条件就为假;如果不能返回结果,WNEN子句中的条件就为真,循环就会结束,控制权转入CLOSE语句。
</P>
<P>EXIT-WHEN语句可以替代简单的IF语句,例如,比较下面两段代码: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>IF</STRONG> count > 100 <STRONG>THEN</STRONG> <BR> <STRONG>EXIT</STRONG>; <BR><STRONG>END</STRONG> <STRONG>IF</STRONG>;
</TD>
<TD vAlign=top
noWrap><STRONG>EXIT</STRONG> <STRONG>WHEN</STRONG> count > 100;</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>这两个语句在逻辑上是等价的,但EXIT-WHEN语句更容易阅读和理解。 </P>
<UL>
<LI>循环标签 </LI></UL>
<P>跟PL/SQL块一样,循环也是可以添加标签。标签必须出现在LOOP语句的开端,语法如下: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><<label_name>><BR><STRONG>LOOP</STRONG><BR> sequence_of_statements<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>而在LOOP语句结束部分出现的标签名称是可选的,语法如下: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><<my_loop>><BR><STRONG>LOOP</STRONG><BR> ...<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG> my_loop;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>在LOOP结束部分使用标签名称能够改善可读性。</P>
<P>无论使用哪种EXIT语句形式,都可以结束一个封闭的LOOP块,而不仅仅局限于当前的LOOP块。只要在我们想结束的封闭LOOP块上添加一个标签,然后像下面这样在EXIT语句中使用这个标签就可以了:</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><<outer>><BR><STRONG>LOOP</STRONG><BR> ...<BR> <STRONG>LOOP</STRONG><BR> ...<BR> <STRONG>EXIT</STRONG> outer <STRONG>WHEN</STRONG> ... <EM>-- exit both loops</EM><BR> <STRONG>END</STRONG> <STRONG>LOOP</STRONG>;<BR> ...<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG> outer;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P class=title2>2、WHILE-LOOP</P>
<P>WHILE-LOOP语句用关键字LOOP和END LOOP把语句序列封闭起来并与一个布尔条件表达式相关联:
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>WHILE</STRONG> condition <STRONG>LOOP</STRONG><BR> sequence_of_statements<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>每次循环之前,程序都是计算布尔表达式的值。如果条件为真,语句序列就会被执行,然后重新返回循环顶部计算布尔表达式的值;如果布尔表达式的值为假或空,控制权就会被交给循环之后的语句。下面看一个例子:
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>WHILE</STRONG> total <= 25000 <STRONG>LOOP</STRONG><BR> ...<BR> <STRONG>SELECT</STRONG> sal<BR> <STRONG>INTO</STRONG> salary<BR> <STRONG>FROM</STRONG> emp<BR> <STRONG>WHERE</STRONG> x = x; ...<BR><BR> total := total + salary;<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>循环的次数是与条件相关的,而且在循环结束之前是未知的。由于条件是在循环顶部测试的,所以语句序列有可能一次都没有执行。在上面的例子中,如果total的初始值比25000大,那么条件值就是假,循环就会被跳过。</P>
<P>有些语言有LOOP UNTIL或是REPEAT
UNTIL这样的结构,在底部测试条件表达式的值。这样,语句序列就会至少执行一次。PL/SQL没有这样的结构,但我们可以变通地使用下面的方法来实现这样的功能:
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>LOOP</STRONG><BR> sequence_of_statements<BR> <STRONG>EXIT</STRONG> <STRONG>WHEN</STRONG> boolean_expression;<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>要保证WHILE循环至少执行一次,在条件表达式中使用初始化过的布尔变量,如下例所示: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap>done := <STRONG>FALSE</STRONG>;<BR><BR><STRONG>WHILE</STRONG> <STRONG>NOT</STRONG> done <STRONG>LOOP</STRONG><BR> sequence_of_statements;<BR> done := boolean_expression;<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>在循环内的语句必须为布尔变量赋上一个新值。否则循环就会无限地执行下去。如下例的两个LOOP语句在逻辑上是等价的:</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>WHILE</STRONG> <STRONG>TRUE</STRONG> <STRONG>LOOP</STRONG> <BR> ... <BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD>
<TD><STRONG>LOOP</STRONG><BR> ...<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P class=title2>3、FOR-LOOP</P>
<P>FOR语句会在指定的整数范围内进行循环操作。循环的内容被关键字FOR和LOOP封闭起来。两个"点"(..)作为范围操作符来使用。语法如下:
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>FOR</STRONG> counter <STRONG>IN</STRONG> [<STRONG>REVERSE</STRONG>] lower_bound..higher_bound <STRONG>LOOP</STRONG><BR> sequence_of_statements<BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>当首次进入FOR循环时,循环的范围就会被确定下来,并且不会重新计算。如下例所示,语句序列会执行三次,每执行一次,循环因子就会增加1。
</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>FOR</STRONG> i <STRONG>IN</STRONG> 1 .. 3 <STRONG>LOOP</STRONG> <EM>-- assign the values 1,2,3 to i</EM><BR> sequence_of_statements <EM>-- executes three times</EM><BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>下例演示了如果下界值等于上界值,循环中的语句序列只执行一次: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>FOR</STRONG> i <STRONG>IN</STRONG> 3 .. 3 <STRONG>LOOP</STRONG> <EM>-- assign the values 3 to i</EM><BR> sequence_of_statements <EM>-- executes one time</EM><BR><STRONG>END</STRONG> <STRONG>LOOP</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>默认情况下,循环总是从下界到上界。不过也可以使用REVERSE关键字,让循环从上界往下界执行。但是要记住,范围的书写格式仍旧是递增顺序的。
</P>
<BLOCKQUOTE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -