⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 第四章 pl-sql的控制结构 - pl-sql用户指南与参考 - whatiswhat.htm

📁 sql初学者不错的教程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FOR</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;<STRONG>REVERSE</STRONG>&nbsp;1&nbsp;..&nbsp;3&nbsp;<STRONG>LOOP</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;assign&nbsp;the&nbsp;values&nbsp;3,2,1&nbsp;to&nbsp;i</EM><BR>&nbsp;&nbsp;sequence_of_statements&nbsp;&nbsp;&nbsp;<EM>--&nbsp;executes&nbsp;three&nbsp;times</EM><BR><STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>FOR循环里,循环计数器只能当作常量来引用且不能为它赋值,如下例: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FOR</STRONG>&nbsp;ctr&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;10&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;<STRONG>NOT</STRONG>&nbsp;finished&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(ctr);&nbsp;&nbsp;&nbsp;<EM>--&nbsp;legal</EM><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;factor&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;ctr&nbsp;*&nbsp;2;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;legal</EM><BR>&nbsp;&nbsp;<STRONG>ELSE</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;ctr&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;10;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;not&nbsp;allowed</EM><BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR><STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <UL>
                          <LI>迭代法 </LI></UL>
                        <P>循环范围的边界可以是文字、变量或表达式,但它们都必须是数字。否则PL/SQL会抛出预定义异常VALUE_ERROR。如下例,下界不一定非得是1。但循环计数器只能是每次增加1。 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>j&nbsp;<STRONG>IN</STRONG>&nbsp;-5&nbsp;..&nbsp;5<BR>k&nbsp;<STRONG>IN</STRONG>&nbsp;<STRONG>REVERSE</STRONG>&nbsp;first..last<BR>step&nbsp;<STRONG>IN</STRONG>&nbsp;0..TRUNC(high/low)&nbsp;*&nbsp;2 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>在PL/SQL内部,它会把边界值赋给一个临时的PLS_INTEGER变量,并在需要的时候把值转换成最接近的整数。PLS_INTEGER的范围是-2**31到2**31之间。所以,如果边界值超过这个范围,我们就会得到一个数字溢出错误: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;hi&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG>&nbsp;:=&nbsp;2&nbsp;**&nbsp;32;<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;hi&nbsp;<STRONG>LOOP</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;causes&nbsp;a&nbsp;鈥檔umeric&nbsp;overflow鈥?error</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>有些语言提供了STEP子句,它能让我们指定循环增量。PL/SQL没有这样的结构,但我们可以在FOR循环内扩大循环计数器的倍数来实现这样的功能。在下面的例子中,我们今天的日期赋给索引表的第一个、第五个和第十五个元素。 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;datelist&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>DATE</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INDEX</STRONG>&nbsp;<STRONG>BY</STRONG>&nbsp;<STRONG>BINARY_INTEGER</STRONG>;<BR><BR>&nbsp;&nbsp;dates&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datelist;<BR>&nbsp;&nbsp;k&nbsp;&nbsp;&nbsp;<STRONG>CONSTANT</STRONG>&nbsp;<STRONG>INTEGER</STRONG>&nbsp;&nbsp;:=&nbsp;5;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;set&nbsp;new&nbsp;increment</EM><BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;3&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;dates(j&nbsp;*&nbsp;k)&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;<STRONG>SYSDATE</STRONG>;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;multiply&nbsp;loop&nbsp;counter&nbsp;by&nbsp;increment</EM><BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <UL>
                          <LI>动态范围 </LI></UL>
                        <P>PL/SQL允许我们在运行时决定循环的范围,如下例所示: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>SELECT</STRONG>&nbsp;COUNT(empno)<BR>&nbsp;&nbsp;<STRONG>INTO</STRONG>&nbsp;emp_count<BR>&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;emp;<BR><BR><STRONG>FOR</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;emp_count&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>emp_count在运行时是未知的;SELECT语句在运行时才返回结果值。 </P>
                        <P>如果循环范围中的下界值超过上界值会怎样呢?如下例所示,循环内的语句序列就不会被执行,控制权直接交给下一个语句: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><EM>--&nbsp;limit&nbsp;becomes&nbsp;1</EM><BR><STRONG>FOR</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;2&nbsp;..&nbsp;LIMIT&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;sequence_of_statements&nbsp;&nbsp;&nbsp;<EM>--&nbsp;executes&nbsp;zero&nbsp;times</EM><BR><STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><EM>--&nbsp;control&nbsp;passes&nbsp;here</EM> 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <UL>
                          <LI>作用域规则 </LI></UL>
                        <P>循环计数器只在循环内部定义,我们不能在循环外引用它。循环退出后,循环计数器就会失效,如下例: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FOR</STRONG>&nbsp;ctr&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;10&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR>sum&nbsp;:=&nbsp;ctr&nbsp;-&nbsp;1;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;not&nbsp;allowed</EM> 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>我们不需要显式声明循环计数器,因为它会被隐式地声明为INTEGER类型本地变量。下面的例子中本地声明覆盖了全局声明: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;ctr&nbsp;<STRONG>INTEGER</STRONG>;<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;ctr&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;25&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;...<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;ctr&nbsp;&gt;&nbsp;10&nbsp;<STRONG>THEN</STRONG>&nbsp;...&nbsp;&nbsp;&nbsp;<EM>--&nbsp;refers&nbsp;to&nbsp;loop&nbsp;counter</EM><BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>如果想在上例中引用全局变量,我们就得借助标签和点标志,例如: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>&lt;&lt;main&gt;&gt;<BR><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;ctr&nbsp;&nbsp;&nbsp;<STRONG>INTEGER</STRONG>;<BR>&nbsp;&nbsp;...<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;ctr&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;25&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;...<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;main.ctr&nbsp;&gt;&nbsp;10&nbsp;<STRONG>THEN</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;refers&nbsp;to&nbsp;global&nbsp;variable</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><STRONG>END</STRONG>&nbsp;main; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>同样的作用域规则也适用于嵌套FOR循环。如下面的例子,两个循环计数器的名字相同,所以,用从内层循环引用外层循环的循环计数器,就必须使用标签和点标志: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>&lt;&lt;outer&gt;&gt;<BR><STRONG>FOR</STRONG>&nbsp;step&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;25&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;step&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;10&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;...<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;outer.step&nbsp;&gt;&nbsp;15&nbsp;<STRONG>THEN</STRONG>&nbsp;...<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>&nbsp;outer; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <UL>
                          <LI>使用EXIT语句 </LI></UL>
                        <P>EXIT语句可以立即结束一个FOR循环。例如,下面的循环语句正常情况应该执行十次,但是,如果FETCH语句取得数据失败,循环就会立即终止,无论它执行过多少次: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FOR</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;10&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;<STRONG>FETCH</STRONG>&nbsp;c1&nbsp;<STRONG>INTO</STRONG>&nbsp;emp_rec;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>EXIT</STRONG>&nbsp;<STRONG>WHEN</STRONG>&nbsp;c1%NOTFOUND;<BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>在使用EXIT时,我们可以结束任何封闭循环,而不仅仅是当前循环。只要在我们想结束的封闭循环上加上标签,然后在EXIT语句中引用它,就能结束做过标记的FOR循环了,如下例: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>&lt;&lt;outer&gt;&gt;<BR><STRONG>FOR</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;5&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;10&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FETCH</STRONG>&nbsp;c1&nbsp;<STRONG>INTO</STRONG>&nbsp;emp_rec;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>EXIT</STRONG>&nbsp;outer&nbsp;<STRONG>WHEN</STRONG>&nbsp;c1%NOTFOUND;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;exit&nbsp;both&nbsp;FOR&nbsp;loops</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>&nbsp;outer;<BR><EM>--&nbsp;control&nbsp;passes&nbsp;here</EM> 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title1>四、顺序控制:GOTO和NULL语句</P>
                        <P>与IF和LOOP语句不通,GOTO和NULL语句对PL/SQL编程来说不是必须的。PL/SQL结构中很少用到GOTO语句。有时,它就是用于简化逻辑的。NULL用于改善可读性使条件语句看起来更加清晰。 
                        </P>
                        <P>滥用GOTO能使结构混乱,不易理解和维护(有时被称为意大利面条式代码 - spaghetti 
                        code)。所以,GOTO语句的使用一定要有节制。例如,要从一个深嵌套中跳到异常控制块,要用异常抛出而不是使用GOTO语句。 
                        </P>
                        <P class=title2>1、GOTO语句</P>
                        <P>GOTO语句可以无条件跳到一个标签处。标签名称在它所处的作用范围内必须是唯一的。执行的时候,GOTO语句会把控制权交给一个做了标记的语句或块。GOTO语句可以向上或向下跳转,示例如下: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>GOTO</STRONG>&nbsp;insert_row;<BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;&lt;&lt;insert_row&gt;&gt;<BR>&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp&nbsp;<STRONG>VALUES</STRONG>&nbsp;...<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>再看一个向上跳转的例子:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;&lt;&lt;update_row&gt;&gt;<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>UPDATE</STRONG>&nbsp;emp&nbsp;<STRONG>SET</S

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -