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

📄 第五章 pl-sql集合与记录(2) - pl-sql用户指南与参考 - whatiswhat.htm

📁 sql初学者不错的教程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                        DELETE语句使用批量绑定,就要用PL/SQL的FORALL语句。</P>
                        <P>如果要在SELECT语句中使用批量绑定,我们就要在SELECT语句后面加上一个BULK 
                        COLLECT子句来代替INTO子句。 </P>
                        <UL>
                          <LI>例一:对DELETE语句应用批量绑定 </LI></UL>
                        <P>下面的DELETE语句只往SQL引擎中发送一次,即使是执行了三次DELETE操作:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;numlist&nbsp;<STRONG>IS</STRONG>&nbsp;VARRAY(20)&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>NUMBER</STRONG>;<BR><BR>&nbsp;&nbsp;depts&nbsp;&nbsp;&nbsp;numlist&nbsp;:=&nbsp;numlist(10,&nbsp;30,&nbsp;70);&nbsp;&nbsp;&nbsp;<EM>--&nbsp;department&nbsp;numbers</EM><BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;depts.FIRST&nbsp;..&nbsp;depts.LAST<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>DELETE</STRONG>&nbsp;<STRONG>FROM</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;deptno&nbsp;=&nbsp;depts(i);<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <UL>
                          <LI>例二:对INSERT语句应用批量绑定 </LI></UL>
                        <P>下例中,我们把5000个零件编号和名称放到索引表中。所有的表元素都向数据库插入两次:第一次使用FOR循环,然后使用FORALL语句。实际上,FORALL版本的代码执行速度要比FOR语句版本的快得多。</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>SQL</STRONG>&gt;&nbsp;<STRONG>SET</STRONG>&nbsp;SERVEROUTPUT&nbsp;<STRONG>ON</STRONG><BR><STRONG>SQL</STRONG>&gt;&nbsp;<STRONG>CREATE</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;parts&nbsp;(pnum&nbsp;<STRONG>NUMBER</STRONG>(4),&nbsp;pname&nbsp;<STRONG>CHAR</STRONG>(15));<BR>Table&nbsp;created.<BR><STRONG>SQL</STRONG>&gt;&nbsp;GET&nbsp;test.sql<BR>1&nbsp;<STRONG>DECLARE</STRONG><BR>2&nbsp;<STRONG>TYPE</STRONG>&nbsp;NumTab&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>NUMBER</STRONG>(4)&nbsp;<STRONG>INDEX</STRONG>&nbsp;<STRONG>BY</STRONG>&nbsp;<STRONG>BINARY_INTEGER</STRONG>;<BR>3&nbsp;<STRONG>TYPE</STRONG>&nbsp;NameTab&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>CHAR</STRONG>(15)&nbsp;<STRONG>INDEX</STRONG>&nbsp;<STRONG>BY</STRONG>&nbsp;<STRONG>BINARY_INTEGER</STRONG>;<BR>4&nbsp;pnums&nbsp;NumTab;<BR>5&nbsp;pnames&nbsp;NameTab;<BR>6&nbsp;t1&nbsp;<STRONG>NUMBER</STRONG>(5);<BR>7&nbsp;t2&nbsp;<STRONG>NUMBER</STRONG>(5);<BR>8&nbsp;t3&nbsp;<STRONG>NUMBER</STRONG>(5);<BR>9<BR>10<BR>11&nbsp;<STRONG>BEGIN</STRONG><BR>12&nbsp;<STRONG>FOR</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;1..5000&nbsp;<STRONG>LOOP</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;load&nbsp;index-by&nbsp;tables</EM><BR>13&nbsp;pnums(j)&nbsp;:=&nbsp;j;<BR>14&nbsp;pnames(j)&nbsp;:=&nbsp;<EM>'Part&nbsp;No.&nbsp;'</EM>&nbsp;||&nbsp;TO_CHAR(j);<BR>15&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR>16&nbsp;t1&nbsp;:=&nbsp;dbms_utility.get_time;<BR>17&nbsp;<STRONG>FOR</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;1..5000&nbsp;<STRONG>LOOP</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;use&nbsp;FOR&nbsp;loop</EM><BR>18&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;parts&nbsp;<STRONG>VALUES</STRONG>&nbsp;(pnums(i),&nbsp;pnames(i));<BR>19&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR>20&nbsp;t2&nbsp;:=&nbsp;dbms_utility.get_time;<BR>21&nbsp;<STRONG>FORALL</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;1..5000&nbsp;&nbsp;&nbsp;<EM>--&nbsp;use&nbsp;FORALL&nbsp;statement</EM><BR>22&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;parts&nbsp;<STRONG>VALUES</STRONG>&nbsp;(pnums(i),&nbsp;pnames(i));<BR>23&nbsp;get_time(t3);<BR>24&nbsp;dbms_output.put_line(<EM>'Execution&nbsp;Time&nbsp;(secs)'</EM>);<BR>25&nbsp;dbms_output.put_line(<EM>'---------------------'</EM>);<BR>26&nbsp;dbms_output.put_line(<EM>'FOR&nbsp;loop:&nbsp;'</EM>&nbsp;||&nbsp;TO_CHAR(t2&nbsp;-&nbsp;t1));<BR>27&nbsp;dbms_output.put_line(<EM>'FORALL:&nbsp;'</EM>&nbsp;||&nbsp;TO_CHAR(t3&nbsp;-&nbsp;t2));<BR>28*&nbsp;<STRONG>END</STRONG>;<BR><STRONG>SQL</STRONG>&gt;&nbsp;/<BR>Execution&nbsp;Time&nbsp;(secs)<BR><EM>---------------------</EM><BR>FOR&nbsp;loop:&nbsp;32<BR>FORALL:&nbsp;3<BR></TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title1>十三、使用FORALL语句</P>
                        <P>关键字FORALL能让PL/SQL引擎在将集合发送到SQL引擎之前,批量导入集合元素。虽然FORALL也包含了迭代的模式,但它并不是简单的FOR循环。它的使用语法如下:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FORALL</STRONG>&nbsp;index&nbsp;<STRONG>IN</STRONG>&nbsp;lower_bound..upper_bound<BR>&nbsp;&nbsp;sql_statement; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>index只能在FORALL语句块内作为集合下标使用。SQL语句必须是引用了集合元素的INSERT、UPDATE或DELETE语句。bound的有效范围是连续的索引号。在这个范围内,SQL引擎为每个索引号执行一次SQL语句。</P>
                        <UL>
                          <LI>例一:使用FORALL操作集合的部分内容 </LI></UL>
                        <P>如下例所示,FORALL循环的边界值可作用于集合的部分内容,不必是全部的元素:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;numlist&nbsp;<STRONG>IS</STRONG>&nbsp;VARRAY(10)&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>NUMBER</STRONG>;<BR><BR>&nbsp;&nbsp;depts&nbsp;&nbsp;&nbsp;numlist&nbsp;:=&nbsp;numlist(20,&nbsp;30,&nbsp;50,&nbsp;55,&nbsp;57,&nbsp;60,&nbsp;70,&nbsp;75,&nbsp;90,&nbsp;92);<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;4&nbsp;..&nbsp;7&nbsp;&nbsp;&nbsp;<EM>--&nbsp;bulk-bind&nbsp;only&nbsp;part&nbsp;of&nbsp;varray</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>UPDATE</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SET</STRONG>&nbsp;sal&nbsp;=&nbsp;sal&nbsp;*&nbsp;1.10<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;deptno&nbsp;=&nbsp;depts(j);<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <UL>
                          <LI>例二:使用集合下标索引的批量绑定 </LI></UL>
                        <P>SQL语句能引用一个以上的集合。但是PL/SQL引擎的批量绑定只能为一个集合添加下标索引。所以,在下面的例子中,对于传递给函数median的集合sals,并没有使用到批量绑定。</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FORALL</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;1..20<BR>&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp2&nbsp;<STRONG>VALUES</STRONG>&nbsp;(enums(i),&nbsp;names(i),&nbsp;median(sals),&nbsp;...); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <UL>
                          <LI>例三:使用FORALL为对象表添加数据 </LI></UL>
                        <P>除了关系表之外,FORALL语句还可以操作对象表,如下例所示:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TYPE</STRONG>&nbsp;pnum&nbsp;<STRONG>AS</STRONG>&nbsp;OBJECT(<BR>&nbsp;&nbsp;n&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG><BR>);<BR>/<BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;partno&nbsp;<STRONG>OF</STRONG>&nbsp;pnum;<BR><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;numtab&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>NUMBER</STRONG>;<BR><BR>&nbsp;&nbsp;nums&nbsp;&nbsp;&nbsp;&nbsp;numtab&nbsp;&nbsp;:=&nbsp;numtab(1,&nbsp;2,&nbsp;3,&nbsp;4);<BR><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;pnumtab&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;pnum;<BR><BR>&nbsp;&nbsp;pnums&nbsp;&nbsp;&nbsp;pnumtab&nbsp;:=&nbsp;pnumtab(pnum(1),&nbsp;pnum(2),&nbsp;pnum(3),&nbsp;pnum(4));<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;pnums.FIRST&nbsp;..&nbsp;pnums.LAST<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;partno<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(pnums(i));<BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;nums.FIRST&nbsp;..&nbsp;nums.LAST<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>DELETE</STRONG>&nbsp;<STRONG>FROM</STRONG>&nbsp;partno<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;n&nbsp;=&nbsp;2&nbsp;*&nbsp;nums(i);<BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;nums.FIRST&nbsp;..&nbsp;nums.LAST<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;partno<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(100&nbsp;+&nbsp;nums(i));<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title2>1、FORALL语句对回滚的影响</P>
                        <P>在FORALL语句中,如果SQL语句引起了一个未捕获异常,以前对数据库的所有操作都会被回滚。但是,如果我们捕获到被抛出的异常并加以处理,此次之前的操作就不会被回滚。举一个例子,假设我们创建了数据表用来存储部门编号和职别: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;emp2&nbsp;(deptno&nbsp;<STRONG>NUMBER</STRONG>(2),&nbsp;job&nbsp;<STRONG>VARCHAR2</STRONG>(15)); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>下一步,为刚才建立的数据表添加一些记录:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp2&nbsp;<STRONG>VALUES</STRONG>(10,&nbsp;<EM>'Clerk'</EM>);<BR><STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp2&nbsp;<STRONG>VALUES</STRONG>(10,&nbsp;<EM>'Clerk'</EM>);<BR><STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp2&nbsp;<STRONG>VALUES</STRONG>(20,&nbsp;<EM>'Bookkeeper'</EM>);&nbsp;&nbsp;&nbsp;<EM>--&nbsp;10-char&nbsp;job&nbsp;title</EM><BR><STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp2&nbsp;<STRONG>VALUES</STRONG>(30,&nbsp;<EM>'Analyst'</EM>);<BR><STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp2&nbsp;<STRONG>VALUES</STRONG>(30,&nbsp;<EM>'Analyst'</EM>); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>然后,我们用下面的UPDATE语句为特定的职称加上七位字符串' (temp)':</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;numlist&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>NUMBER</STRONG>;<BR><BR>&nbsp;&nbsp;depts&nbsp;&nbsp;&nbsp;numlist&nbsp;:=&nbsp;numlist(10,&nbsp;20,&nbsp;30);<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;depts.FIRST&nbsp;..&nbsp;depts.LAST<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>UPDATE</STRONG>&nbsp;emp2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SET</STRONG>&nbsp;job&nbsp;=&nbsp;job&nbsp;||&nbsp;<EM>'&nbsp;(temp)'</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;deptno&nbsp;=&nbsp;depts(j);<BR>&nbsp;&nbsp;<EM>--&nbsp;raises&nbsp;a&nbsp;"value&nbsp;too&nbsp;large"&nbsp;exception</EM><BR><STRONG>EXCEPTION</STRONG><BR>&nbsp;&nbsp;<STRONG>WHEN</STRONG>&nbsp;<STRONG>OTHERS</STRONG>&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>COMMIT</STRONG>;<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>SQL引擎会执行UPDATE语句三次,第一次成功,但在第二次会因字符串值'Bookkeeper 
                        (temp)'太长而无法赋给job字段,所以就会执行失败。这种情况下,只有第二条语句回滚。</P>
                        <P>只要有SQL语句抛出异常,FORALL语句就会终止执行。在上面的例子中,第二个UPDATE语句抛出了异常,第三个语句就不会被执行了。</P>
                        <P 
                        class=title2>2、使用%BULK_ROWCOUNT属性来计算FORALL语句所影响到的行数</P>
                        <P>处理SQL数据操作语句时,SQL引擎会隐式地打开一个名为SQL的游标。这个游标的标量属性%FOUND、%ISOPEN、%NOTFOUND和%ROWCOUNT,能够提供最近一次执行的SQL数据操作语句信息。</P>
                        <P>SQL游标还有一个专门为FORALL设计的复合属性%BULK_ROWCOUNT。这个属性有些像索引表。它的第i个元素保存了第i次的 
                        INSERT或UPDATE或DELETE语句所影响到的行数。如果第i次操作没有行被影响,%BULK_ROWCOUNT(i)就返回零。下面来看一个例子:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;numlist&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>NUMBER</STRONG>;<BR><BR>&nbsp;&nbsp;depts&nbsp;&nbsp;&nbsp;numlist&nbsp;:=&nbsp;numlist(10,&nbsp;20,&nbsp;50);<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;depts.FIRST&nbsp;..&nbsp;depts.LAST<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>UPDATE</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SET</STRONG>&nbsp;sal&nbsp;=&nbsp;sal&nbsp;*&nbsp;1.10<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;deptno&nbsp;=&nbsp;depts(j);<BR>&nbsp;&nbsp;<EM>--&nbsp;Did&nbsp;the&nbsp;3rd&nbsp;UPDATE&nbsp;statement&nbsp;affect&nbsp;any&nbsp;rows?</EM><BR>&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;<STRONG>SQL</STRONG>%BULK_ROWCOUNT(3)&nbsp;=&nbsp;0&nbsp;<STRONG>THEN</STRONG>&nbsp;...<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>FORALL语句和%BULK_ROWCOUNT属性使用同样的下标索引。如果FORALL使用下标索引的范围在5到10的话,那么% 
                        BULK_ROWCOUNT的也是。对于插入操作来说,%BULK_ROWCOUNT的结果一般是1,但是对于INSERT 
                        ... 
                        SELECT这样的结构来说,%BULK_ROWCOUNT的值就有可能大于1。例如,下面的FORALL语句在循环插入数据的过程中,每次插入的行的个数都是不固定的,%BULK_ROWCOUNT可以记录每次插入的行数: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>SET</STRONG>&nbsp;SERVEROUTPUT&nbsp;<STRONG>ON</STRONG>;<BR><BR><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;num_tab&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;<STRONG>NUMBER</STRONG>;<BR><BR>&nbsp;&nbsp;deptnums&nbsp;&nbsp;&nbsp;num_tab;<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;deptno<BR>&nbsp;&nbsp;<STRONG>BULK</STRONG>&nbsp;<STRONG>COLLECT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;deptnums<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;dept;<BR><BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;deptnums.COUNT<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp_by_dept<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;empno,&nbsp;deptno<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;deptno&nbsp;=&nbsp;deptnums(i);<BR><BR>&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;deptnums.COUNT&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;Count&nbsp;how&nbsp;many&nbsp;rows&nbsp;were&nbsp;inserted&nbsp;for&nbsp;each&nbsp;department;&nbsp;that&nbsp;is,</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;how&nbsp;many&nbsp;employees&nbsp;are&nbsp;in&nbsp;each&nbsp;department.</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;DBMS_OUTPUT.put_line(&nbsp;&nbsp;&nbsp;<EM>'Dept&nbsp;'</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;||&nbsp;deptnums(i)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;||&nbsp;<EM>':&nbsp;inserted&nbsp;'</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;||&nbsp;<STRONG>SQL</STRONG>%BULK_ROWCOUNT(i)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;||&nbsp;<EM>'&nbsp;records'</EM>);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><BR>&nbsp;&nbsp;DBMS_OUTPUT.put_line(<EM>'Total&nbsp;records&nbsp;inserted&nbsp;='</EM>&nbsp;||&nbsp;<STRONG>SQL</STRONG>%ROWCOUNT);<BR><STRONG>END</STRONG>;<BR>/ 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>我们还可以在批量绑定中使用标量属性%FOUND、%ISOPEN、%NOTFOUND和%ROWCOUNT。例如,%ROWCOUNT会返回所有的SQL语句处理的总行数。</P>

⌨️ 快捷键说明

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