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

📄 第九章 pl-sql包 - pl-sql用户指南与参考 - whatiswhat.htm

📁 sql初学者不错的教程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;trans_data&nbsp;<STRONG>AS</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;bodiless&nbsp;package</EM><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;timerec&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</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;transrec&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>(<BR>&nbsp;&nbsp;&nbsp;&nbsp;CATEGORY&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;ACCOUNT&nbsp;&nbsp;&nbsp;&nbsp;INT,<BR>&nbsp;&nbsp;&nbsp;&nbsp;amount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;time_of&nbsp;&nbsp;&nbsp;&nbsp;timerec<BR>&nbsp;&nbsp;);<BR><BR>&nbsp;&nbsp;minimum_balance&nbsp;&nbsp;&nbsp;<STRONG>CONSTANT</STRONG>&nbsp;<STRONG>REAL</STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;10.00;<BR>&nbsp;&nbsp;number_processed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;INT;<BR>&nbsp;&nbsp;insufficient_funds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>EXCEPTION</STRONG>;<BR><STRONG>END</STRONG>&nbsp;trans_data; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>包trans_data不需要包体,因为类型、常量、变量和异常并没有实现部分。这样的包能让我们定义全局变量,可供子程序和数据库触发器使用。 
                        </P>
                        <P class=title2>1、引用包的内容</P>
                        <P>如果要引用包内声明的类型、常量、变量、异常和子程序等,就得使用点标识: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>package_name.type_name<BR>package_name.item_name<BR>package_name.subprogram_name<BR>package_name.call_spec_name 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>我们可以从数据库触发器、存储子程序、3GL(第三代程序语言)应用程序和各种Oracle工具中引用包中的内容。例如,我们可以从SQL*Plus中调用过程hire_employee: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>SQL</STRONG>&gt;&nbsp;CALL&nbsp;emp_actions.hire_employee(<EM>'TATE'</EM>,&nbsp;<EM>'CLERK'</EM>,&nbsp;...); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>下例中,我们可以从一个嵌入到Pro*C的匿名PL/SQL块调用同样的过程。实参emp_name和job_title是主变量(即声明在主环境中的变量)。 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>EXEC&nbsp;<STRONG>SQL</STRONG>&nbsp;<STRONG>EXECUTE</STRONG><BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;emp_actions.hire_employee(:emp_name,&nbsp;:job_title,&nbsp;...); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <UL>
                          <LI>约束 </LI></UL>
                        <P>我们不能直接或间接地引用远程打包变量。例如,我们不能远程调用下面的过程,因为它在参数初始化子句中引用了打包变量: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;random&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;seed&nbsp;<STRONG>NUMBER</STRONG>;<BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;initialize&nbsp;(starter&nbsp;<STRONG>IN</STRONG>&nbsp;<STRONG>NUMBER</STRONG>&nbsp;:=&nbsp;seed,&nbsp;...); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>同样,我们也不能在包的内部引用主变量。 </P>
                        <P class=title1>四、理解包体</P>
                        <P>包体是对包说明的实现。也就是说包体中包含了包说明中声明的每一个游标和子程序的实现。一定要记住,包体内实现的内容只有在包说明中声明之后才能在包外引用。为了匹配包说明和包体,PL/SQL做了一个token-by-token的子程序头比较。所以,除了空白内容,头部内容必须完全一致。否则, 
                        PL/SQL就会抛出异常,如下例所示: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;emp_actions&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;calc_bonus(date_hired&nbsp;emp.hiredate%<STRONG>TYPE</STRONG>,&nbsp;...);<BR><STRONG>END</STRONG>&nbsp;emp_actions;<BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;<STRONG>BODY</STRONG>&nbsp;emp_actions&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;calc_bonus(date_hired&nbsp;<STRONG>DATE</STRONG>,&nbsp;...)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<EM>--&nbsp;parameter&nbsp;declaration&nbsp;raises&nbsp;an&nbsp;exception&nbsp;because&nbsp;'DATE'</EM><BR>&nbsp;&nbsp;<EM>--&nbsp;does&nbsp;not&nbsp;match&nbsp;'emp.hiredate%TYPE'&nbsp;word&nbsp;for&nbsp;word</EM><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG>&nbsp;...&nbsp;<STRONG>END</STRONG>;<BR><STRONG>END</STRONG>&nbsp;emp_actions; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>包体能包含私有声明,可以定义类型和其它所需的内容。这些声明的内容对于包体来说是本地的。因此,声明的内容在包体之外是无法访问的。与包说明部分不同的是,包体的声明部分可以包含子程序体。 
                        </P>
                        <P>在包体的声明部分之后是一个可选的初始化部分,一般是用于初始化包中变量。 </P>
                        <P>包初始化部分起到的作用并不大,与子程序不同,它不能被调用或是接受参数。因此,包初始化部分只能在我们首次引用包的时候运行一次。 
                        </P>
                        <P>请记住,如果一个包说明只声明了类型、常量、变量、异常和调用说明,那么,包体部分就不是必需的了。但是,包体可以用于初始化包说明中声明的内容。 
                        </P>
                        <P class=title1>五、包特性的例子</P>
                        <P>下面是一个名为emp_actions的包。包说明声明了类型、游标、异常和子程序: </P>
                        <OL>
                          <LI>类型EmpRecTyp和DeptRecTyp 
                          <LI>游标desc_salary 
                          <LI>异常invalid_salary 
                          <LI>函数hire_employee和raise_salary 
                          <LI>过程fire_empire和raise_salary </LI></OL>
                        <P>在编写包之后,我们就可以开发引用它声明的类型,调用它的子程序、游标和异常的应用程序。创建包时,它就会被存放在Oracle数据库中供广泛地调用。 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;emp_actions&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;<EM>/*&nbsp;Declare&nbsp;externally&nbsp;visible&nbsp;types,&nbsp;cursor,&nbsp;exception.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;emprectyp&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>(<BR>&nbsp;&nbsp;&nbsp;&nbsp;emp_id&nbsp;&nbsp;&nbsp;INT,<BR>&nbsp;&nbsp;&nbsp;&nbsp;salary&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG><BR>&nbsp;&nbsp;);<BR><BR>&nbsp;&nbsp;<STRONG>TYPE</STRONG>&nbsp;deptrectyp&nbsp;<STRONG>IS</STRONG>&nbsp;<STRONG>RECORD</STRONG>(<BR>&nbsp;&nbsp;&nbsp;&nbsp;dept_id&nbsp;&nbsp;&nbsp;&nbsp;INT,<BR>&nbsp;&nbsp;&nbsp;&nbsp;LOCATION&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG><BR>&nbsp;&nbsp;);<BR><BR>&nbsp;&nbsp;<STRONG>CURSOR</STRONG>&nbsp;desc_salary&nbsp;<STRONG>RETURN</STRONG>&nbsp;emprectyp;<BR><BR>&nbsp;&nbsp;invalid_salary&nbsp;&nbsp;&nbsp;<STRONG>EXCEPTION</STRONG>;<BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Declare&nbsp;externally&nbsp;callable&nbsp;subprograms.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;hire_employee(<BR>&nbsp;&nbsp;&nbsp;&nbsp;ename&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;job&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;mgr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;sal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;comm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;deptno&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG><BR>&nbsp;&nbsp;)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;INT;<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;fire_employee(emp_id&nbsp;INT);<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;raise_salary(emp_id&nbsp;INT,&nbsp;grade&nbsp;INT,&nbsp;amount&nbsp;<STRONG>REAL</STRONG>);<BR><BR>&nbsp;&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;nth_highest_salary(n&nbsp;INT)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;emprectyp;<BR><STRONG>END</STRONG>&nbsp;emp_actions;<BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;<STRONG>BODY</STRONG>&nbsp;emp_actions&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;number_hired&nbsp;&nbsp;&nbsp;INT;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;visible&nbsp;only&nbsp;in&nbsp;this&nbsp;package</EM><BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Fully&nbsp;define&nbsp;cursor&nbsp;specified&nbsp;in&nbsp;package.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>CURSOR</STRONG>&nbsp;desc_salary&nbsp;<STRONG>RETURN</STRONG>&nbsp;emprectyp&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;&nbsp;&nbsp;empno,&nbsp;sal<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ORDER</STRONG>&nbsp;<STRONG>BY</STRONG>&nbsp;sal&nbsp;<STRONG>DESC</STRONG>;<BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Fully&nbsp;define&nbsp;subprograms&nbsp;specified&nbsp;in&nbsp;package.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;hire_employee(<BR>&nbsp;&nbsp;&nbsp;&nbsp;ename&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;job&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;mgr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;sal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;comm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>,<BR>&nbsp;&nbsp;&nbsp;&nbsp;deptno&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG><BR>&nbsp;&nbsp;)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;INT&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;new_empno&nbsp;&nbsp;&nbsp;INT;<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;empno_seq.<STRONG>NEXTVAL</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTO</STRONG>&nbsp;new_empno<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;DUAL;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(new_empno,&nbsp;ename,&nbsp;job,&nbsp;mgr,&nbsp;<STRONG>SYSDATE</STRONG>,&nbsp;sal,&nbsp;comm,&nbsp;deptno);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;number_hired&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;number_hired&nbsp;+&nbsp;1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;new_empno;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;hire_employee;<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;fire_employee(emp_id&nbsp;INT)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><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;empno&nbsp;=&nbsp;emp_id;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;fire_employee;<BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Define&nbsp;local&nbsp;function,&nbsp;available&nbsp;only&nbsp;inside&nbsp;package.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;sal_ok(RANK&nbsp;INT,&nbsp;salary&nbsp;<STRONG>REAL</STRONG>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>BOOLEAN</STRONG>&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;min_sal&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;max_sal&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>;<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;losal,&nbsp;hisal<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTO</STRONG>&nbsp;min_sal,&nbsp;max_sal<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;salgrade<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;grade&nbsp;=&nbsp;RANK;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;(salary&nbsp;&gt;=&nbsp;min_sal)&nbsp;<STRONG>AND</STRONG>(salary&nbsp;&lt;=&nbsp;max_sal);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;sal_ok;<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;raise_salary(emp_id&nbsp;INT,&nbsp;grade&nbsp;INT,&nbsp;amount&nbsp;<STRONG>REAL</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;salary&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>;<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;sal<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTO</STRONG>&nbsp;salary<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;empno&nbsp;=&nbsp;emp_id;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;sal_ok(grade,&nbsp;salary&nbsp;+&nbsp;amount)&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>UPDATE</STRONG>&nbsp;emp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SET</STRONG>&nbsp;sal&nbsp;=&nbsp;sal&nbsp;+&nbsp;amount<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;empno&nbsp;=&nbsp;emp_id;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ELSE</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RAISE</STRONG>&nbsp;invalid_salary;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;raise_salary;<BR><BR>&nbsp;&nbsp;<STRONG>FUNCTION</STRONG>&nbsp;nth_highest_salary(n&nbsp;INT)<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;emprectyp&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;emp_rec&nbsp;&nbsp;&nbsp;emprectyp;<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>OPEN</STRONG>&nbsp;desc_salary;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;i&nbsp;<STRONG>IN</STRONG>&nbsp;1&nbsp;..&nbsp;n&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FETCH</STRONG>&nbsp;desc_salary<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTO</STRONG>&nbsp;emp_rec;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>CLOSE</STRONG>&nbsp;desc_salary;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RETURN</STRONG>&nbsp;emp_rec;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;nth_highest_salary;<BR><STRONG>BEGIN</STRONG>&nbsp;&nbsp;&nbsp;<EM>--&nbsp;initialization&nbsp;part&nbsp;starts&nbsp;here</EM><BR>&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;emp_audit<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(<STRONG>SYSDATE</STRONG>,&nbsp;<STRONG>USER</STRONG>,&nbsp;<EM>'emp_actions'</EM>);<BR><BR>&nbsp;&nbsp;number_hired&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;0;<BR><STRONG>END</STRONG>&nbsp;emp_actions; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>请记住,包初始化部分只是在我们首次引用包的时候执行一次。所以,在上面的例子中,只有一行数据被插入数据表emp_audit。同样,变量number_hired也只被初始化一次。 
                        </P>
                        <P>每次hire_employee被调用的时候,变量nubmer_hired就会被更新。但是,number_hired所记录的数字是与特定的会话相关的。也就是说,计数的结果是与一个用户所处理的新雇员的个数,而不是所有会话处理过的雇员个数。 
                        </P>
                        <P>在下面的例子中,我们把一些典型的银行事务进行打包。假设借款与贷款事务都是在营业时间之后通过自动出纳机处理,然后在第二天早上应用到账户中去。 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 

⌨️ 快捷键说明

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