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

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

📁 sql初学者不错的教程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title2>3、使用RETURNING INTO子句将DML的操作结果绑定到集合</P>
                        <P>我们还可以在INSERT、UPDATE或DELETE语句的RETURNING INTO子句中使用BULK 
                        COLLECT来进行数据绑定,示例如下: </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;emp.empno%<STRONG>TYPE</STRONG>;<BR><BR>&nbsp;&nbsp;enums&nbsp;&nbsp;&nbsp;numlist;<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>DELETE</STRONG>&nbsp;<STRONG>FROM</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;deptno&nbsp;=&nbsp;20<BR>&nbsp;&nbsp;&nbsp;&nbsp;RETURNING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;empno<BR>&nbsp;&nbsp;<STRONG>BULK</STRONG>&nbsp;<STRONG>COLLECT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;enums;<BR>&nbsp;&nbsp;<EM>--&nbsp;if&nbsp;there&nbsp;were&nbsp;five&nbsp;employees&nbsp;in&nbsp;department&nbsp;20,</EM><BR>&nbsp;&nbsp;<EM>--&nbsp;then&nbsp;enums&nbsp;contains&nbsp;five&nbsp;employee&nbsp;numbers</EM><BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title2>4、BULK COLLECT的限制</P>
                        <P>下面是使用BULK COLLECT的一些限制: </P>
                        <OL>
                          <LI>不能对使用字符串类型作键的关联数组使用BULK COLLECT子句。 
                          <LI>只能在服务器端的程序中使用BULK 
                          COLLECT,如果在客户端使用,就会产生一个不支持这个特性的错误。 
                          <LI>BULK COLLECT INTO的目标对象必须是集合类型,如下例所示: 
                          <BLOCKQUOTE>
                            <TABLE>
                              <TBODY>
                              <TR>
                                <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;namelist&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>TABLE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;emp.ename%<STRONG>TYPE</STRONG>;<BR><BR>&nbsp;&nbsp;names&nbsp;&nbsp;&nbsp;&nbsp;namelist;<BR>&nbsp;&nbsp;salary&nbsp;&nbsp;&nbsp;emp.sal%<STRONG>TYPE</STRONG>;<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;ename,&nbsp;sal<BR>&nbsp;&nbsp;<STRONG>BULK</STRONG>&nbsp;<STRONG>COLLECT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;names,&nbsp;salary&nbsp;&nbsp;&nbsp;<EM>--&nbsp;illegal&nbsp;target</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;<STRONG>ROWNUM</STRONG>&nbsp;&lt;&nbsp;50;<BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>; 
                                </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                          <LI>复合目标(如对象类型)不能在RETURNING INTO子句中使用。 
                          <LI>如果有多个隐式的数据类型转换的情况存在,多重复合目标就不能在BULK COLLECT 
                          INTO子句中使用。 
                          <LI>如果有一个隐式的数据类型转换,复合目标的集合(如对象类型集合)就不能用于BULK COLLECT 
                          INTO子句中。 </LI></OL>
                        <P class=title2>5、把FORALL和BULK COLLECTION结合起来使用</P>
                        <P>我们可以把BULK 
                        COLLECT和FORALL语句结合起来使用,这时,SQL引擎会批量绑定字段值。下例中,如果集合depts有三个元素,每个元素都能执行五次DELETE操作,当语句执行完毕的时候,enums中就会有十五个元素: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FORALL</STRONG>&nbsp;j&nbsp;<STRONG>IN</STRONG>&nbsp;depts.FIRST&nbsp;..&nbsp;depts.LAST<BR>&nbsp;&nbsp;<STRONG>DELETE</STRONG>&nbsp;<STRONG>FROM</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;empno&nbsp;=&nbsp;depts(j)<BR>&nbsp;&nbsp;&nbsp;&nbsp;RETURNING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;empno<BR>&nbsp;&nbsp;<STRONG>BULK</STRONG>&nbsp;<STRONG>COLLECT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;enums; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>我们不能在FORALL语句中使用SELECT ... BULK 
                        COLLECT语句。否则,就会得到一条错误消息:不能在SELECT语句中同时使用FORALL和BULK 
                        COLLECT INTO(cannot use FORALL and BULK COLLECT INTO 
                        together in SELECT statements)。 </P>
                        <P class=title2>6、使用主数组进行批量绑定 </P>
                        <P>客户端程序可以使用匿名PL/SQL块来把数据批量地从主数组中输入或批量地输出到主数组。实际上,这是与服务器端交互传递集合的最高效的方法。</P>
                        <P>主数组是声明在主环境中的,如OCI或Pro*C程序,并且必须以冒号为前缀,以区别于PL/SQL集合。在下面的例子中,DELETE语句中使用到一个输入主数组。运行时,匿名PL/SQL块被发送到数据库服务器端执行: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;<EM>--&nbsp;assume&nbsp;that&nbsp;values&nbsp;were&nbsp;assigned&nbsp;to&nbsp;the&nbsp;host&nbsp;array</EM><BR>&nbsp;&nbsp;<EM>--&nbsp;and&nbsp;host&nbsp;variables&nbsp;in&nbsp;the&nbsp;host&nbsp;environment</EM><BR>&nbsp;&nbsp;<STRONG>FORALL</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;:lower..:upper<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>DELETE</STRONG>&nbsp;<STRONG>FROM</STRONG>&nbsp;emp&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;deptno&nbsp;=&nbsp;:depts(i);<BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title1>十五、什么是记录</P>
                        <P>记录就是相关的数据项集中存储在一个单元中,每项都有它自己的名字和数据类型。假定我们有关于雇员的各种数据信息,如名字、薪水和雇佣日期,这些项在逻辑上是相关联的,但类型不相似。记录可以把它所拥有的每一项当作一个逻辑单元,这样就便于组织和表现信息。 
                        </P>
                        <P>%ROWTYPE属性能让我们声明代表数据表中一行记录的类型。但是我们不能利用它指定或声明自己的数据类型。不过没关系,RECORD关键字可以满足我们定义自己的记录的要求。 
                        </P>
                        <P class=title1>十六、定义和声明记录</P>
                        <P>要创建记录,我们就得先声明记录类型,然后声明该类型的记录。我们可以在PL/SQL块、子程序或包的声明部分使用下面的语法来定义RECORD类型:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>TYPE</STRONG>&nbsp;type_name&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>&nbsp;(field_declaration[,field_declaration]...); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>其中field_declaration的形式如下: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>field_name&nbsp;field_type&nbsp;[[<STRONG>NOT</STRONG>&nbsp;<STRONG>NULL</STRONG>]&nbsp;{:=&nbsp;|&nbsp;<STRONG>DEFAULT</STRONG>}&nbsp;expression] 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>type_name是声明记录用的类型区分符,field_type是除了REF 
                        CURSOR以外的任何PL/SQL数据类型,expression的结果值与field_type相同。 </P>
                        <P>注意:与VARRAY类型和TABLE(嵌套)类型不同的是,RECORD是不能存在于数据库中的。</P>
                        <P>创建记录时也可以使用%TYPE和%ROWTYPE来指定记录各个域的类型。下例中,我们定义了一个名为DeptRec的记录类型:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;deptrec&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>(<BR>&nbsp;&nbsp;&nbsp;&nbsp;dept_id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dept.deptno%<STRONG>TYPE</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;dept_name&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(14),<BR>&nbsp;&nbsp;&nbsp;&nbsp;dept_loc&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(13)<BR>&nbsp;&nbsp;);<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>在下面的例子中,我们在记录类型中包含对象、集合和其他的记录(又叫嵌套记录)。但是对象类型中不能把RECORD类型作为它的属性。 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;timerec&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>(<BR>&nbsp;&nbsp;&nbsp;&nbsp;seconds&nbsp;&nbsp;&nbsp;<STRONG>SMALLINT</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;minutes&nbsp;&nbsp;&nbsp;<STRONG>SMALLINT</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SMALLINT</STRONG><BR>&nbsp;&nbsp;);<BR><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;flightrec&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>(<BR>&nbsp;&nbsp;&nbsp;&nbsp;flight_no&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTEGER</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;plane_id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(10),<BR>&nbsp;&nbsp;&nbsp;&nbsp;captain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;employee,&nbsp;&nbsp;&nbsp;<EM>--&nbsp;declare&nbsp;object</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;passengers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passengerlist,&nbsp;&nbsp;&nbsp;<EM>--&nbsp;declare&nbsp;varray</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;depart_time&nbsp;&nbsp;&nbsp;&nbsp;timerec,&nbsp;&nbsp;&nbsp;<EM>--&nbsp;declare&nbsp;nested&nbsp;record</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;airport_code&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(10)<BR>&nbsp;&nbsp;);<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;...<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>下面的例子演示了如何将函数的返回类型指定为RECORD类型: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;emprec&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>(<BR>&nbsp;&nbsp;&nbsp;&nbsp;emp_id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG>(4),<BR>&nbsp;&nbsp;&nbsp;&nbsp;last_name&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(10),<BR>&nbsp;&nbsp;&nbsp;&nbsp;dept_num&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG>(2),<BR>&nbsp;&nbsp;&nbsp;&nbsp;job_title&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(9),<BR>&nbsp;&nbsp;&nbsp;&nbsp;salary&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>NUMBER</STRONG>(7,&nbsp;2)<BR>&nbsp;&nbsp;);<BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;nth_highest_salary(n&nbsp;<STRONG>INTEGER</STRONG>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;emprec&nbsp;<STRONG>IS</STRONG>&nbsp;...<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title2>1、声明记录</P>
                        <P>一旦定义了RECORD类型,我们就可以声明该类型的记录。如下例所示,标识符item_info代表了整条记录: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>DECLARE</STRONG><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;stockitem&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>(<BR>&nbsp;&nbsp;&nbsp;&nbsp;item_no&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTEGER</STRONG>(3),<BR>&nbsp;&nbsp;&nbsp;&nbsp;description&nbsp;&nbsp;&nbsp;<STRONG>VARCHA

⌨️ 快捷键说明

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