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

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

📁 sql初学者不错的教程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;bank_transactions&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;<EM>/*&nbsp;Declare&nbsp;externally&nbsp;visible&nbsp;constant.&nbsp;*/</EM><BR>&nbsp;&nbsp;minimum_balance&nbsp;&nbsp;&nbsp;<STRONG>CONSTANT</STRONG>&nbsp;<STRONG>REAL</STRONG>&nbsp;:=&nbsp;100.00;<BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Declare&nbsp;externally&nbsp;callable&nbsp;procedures.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;apply_transactions;<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;enter_transaction(acct&nbsp;INT,&nbsp;kind&nbsp;<STRONG>CHAR</STRONG>,&nbsp;amount&nbsp;<STRONG>REAL</STRONG>);<BR><STRONG>END</STRONG>&nbsp;bank_transactions;<BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;<STRONG>BODY</STRONG>&nbsp;bank_transactions&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;<EM>/*&nbsp;Declare&nbsp;global&nbsp;variable&nbsp;to&nbsp;hold&nbsp;transaction&nbsp;status.&nbsp;*/</EM><BR>&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;<STRONG>VARCHAR2</STRONG>(70)&nbsp;:=&nbsp;<EM>'Unknown'</EM>;<BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Use&nbsp;forward&nbsp;declarations&nbsp;because&nbsp;apply_transactions<BR>&nbsp;&nbsp;calls&nbsp;credit_account&nbsp;and&nbsp;debit_account,&nbsp;which&nbsp;are&nbsp;not<BR>&nbsp;&nbsp;yet&nbsp;declared&nbsp;when&nbsp;the&nbsp;calls&nbsp;are&nbsp;made.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;credit_account(acct&nbsp;INT,&nbsp;credit&nbsp;<STRONG>REAL</STRONG>);<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;debit_account(acct&nbsp;INT,&nbsp;debit&nbsp;<STRONG>REAL</STRONG>);<BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Fully&nbsp;define&nbsp;procedures&nbsp;specified&nbsp;in&nbsp;package.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;apply_transactions&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<EM>/*&nbsp;Apply&nbsp;pending&nbsp;transactions&nbsp;in&nbsp;transactions&nbsp;table<BR>&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;accounts&nbsp;table.&nbsp;Use&nbsp;cursor&nbsp;to&nbsp;fetch&nbsp;rows.&nbsp;*/</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>CURSOR</STRONG>&nbsp;trans_cursor&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acct_id,&nbsp;kind,&nbsp;amount<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;transactions<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;status&nbsp;=&nbsp;<EM>'Pending'</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ORDER</STRONG>&nbsp;<STRONG>BY</STRONG>&nbsp;time_tag<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;<STRONG>UPDATE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;status;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;to&nbsp;lock&nbsp;rows</EM><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;trans&nbsp;<STRONG>IN</STRONG>&nbsp;trans_cursor&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;trans.kind&nbsp;=&nbsp;<EM>'D'</EM>&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debit_account(trans.acct_id,&nbsp;trans.amount);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ELSIF</STRONG>&nbsp;trans.kind&nbsp;=&nbsp;<EM>'C'</EM>&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;credit_account(trans.acct_id,&nbsp;trans.amount);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ELSE</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;<EM>'Rejected'</EM>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>UPDATE</STRONG>&nbsp;transactions<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SET</STRONG>&nbsp;status&nbsp;=&nbsp;new_status<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;<STRONG>CURRENT</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;trans_cursor;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;apply_transactions;<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;enter_transaction(<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;&nbsp;&nbsp;&nbsp;&nbsp;<EM>/*&nbsp;Add&nbsp;a&nbsp;transaction&nbsp;to&nbsp;transactions&nbsp;table.&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;&nbsp;&nbsp;&nbsp;&nbsp;acct&nbsp;INT,&nbsp;kind&nbsp;<STRONG>CHAR</STRONG>,&nbsp;amount&nbsp;<STRONG>REAL</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;transactions<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(acct,&nbsp;kind,&nbsp;amount,&nbsp;<EM>'Pending'</EM>,&nbsp;<STRONG>SYSDATE</STRONG>);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;enter_transaction;<BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Define&nbsp;local&nbsp;procedures,&nbsp;available&nbsp;only&nbsp;in&nbsp;package.&nbsp;*/</EM><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;do_journal_entry(<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;&nbsp;&nbsp;&nbsp;<EM>/*&nbsp;Record&nbsp;transaction&nbsp;in&nbsp;journal.&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;&nbsp;&nbsp;&nbsp;acct&nbsp;INT,&nbsp;kind&nbsp;<STRONG>CHAR</STRONG>,&nbsp;new_bal&nbsp;<STRONG>REAL</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;journal<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(acct,&nbsp;kind,&nbsp;new_bal,&nbsp;<STRONG>SYSDATE</STRONG>);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;kind&nbsp;=&nbsp;<EM>'D'</EM>&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;<EM>'Debit&nbsp;applied'</EM>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ELSE</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;<EM>'Credit&nbsp;applied'</EM>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;do_journal_entry;<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;credit_account(acct&nbsp;INT,&nbsp;credit&nbsp;<STRONG>REAL</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<EM>/*&nbsp;Credit&nbsp;account&nbsp;unless&nbsp;account&nbsp;number&nbsp;is&nbsp;bad.&nbsp;*/</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;old_balance&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;new_balance&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>;<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;balance<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTO</STRONG>&nbsp;old_balance<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;accounts<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;acct_id&nbsp;=&nbsp;acct<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;<STRONG>UPDATE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;balance;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;to&nbsp;lock&nbsp;the&nbsp;row</EM><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;new_balance&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;old_balance&nbsp;+&nbsp;credit;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>UPDATE</STRONG>&nbsp;accounts<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SET</STRONG>&nbsp;balance&nbsp;=&nbsp;new_balance<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;acct_id&nbsp;=&nbsp;acct;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;do_journal_entry(acct,&nbsp;<EM>'C'</EM>,&nbsp;new_balance);<BR>&nbsp;&nbsp;<STRONG>EXCEPTION</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHEN</STRONG>&nbsp;NO_DATA_FOUND&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;<EM>'Bad&nbsp;account&nbsp;number'</EM>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHEN</STRONG>&nbsp;<STRONG>OTHERS</STRONG>&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;SUBSTR(<STRONG>SQLERRM</STRONG>,&nbsp;1,&nbsp;70);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;credit_account;<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;debit_account(acct&nbsp;INT,&nbsp;debit&nbsp;<STRONG>REAL</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<EM>/*&nbsp;Debit&nbsp;account&nbsp;unless&nbsp;account&nbsp;number&nbsp;is&nbsp;bad&nbsp;or<BR>&nbsp;&nbsp;&nbsp;&nbsp;account&nbsp;has&nbsp;insufficient&nbsp;funds.&nbsp;*/</EM><BR>&nbsp;&nbsp;&nbsp;&nbsp;old_balance&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;new_balance&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>REAL</STRONG>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;insufficient_funds&nbsp;&nbsp;&nbsp;<STRONG>EXCEPTION</STRONG>;<BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;balance<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INTO</STRONG>&nbsp;old_balance<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;accounts<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;acct_id&nbsp;=&nbsp;acct<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;<STRONG>UPDATE</STRONG>&nbsp;<STRONG>OF</STRONG>&nbsp;balance;&nbsp;&nbsp;&nbsp;<EM>--&nbsp;to&nbsp;lock&nbsp;the&nbsp;row</EM><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;new_balance&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;old_balance&nbsp;-&nbsp;debit;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>IF</STRONG>&nbsp;new_balance&nbsp;&gt;=&nbsp;minimum_balance&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>UPDATE</STRONG>&nbsp;accounts<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SET</STRONG>&nbsp;balance&nbsp;=&nbsp;new_balance<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHERE</STRONG>&nbsp;acct_id&nbsp;=&nbsp;acct;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_journal_entry(acct,&nbsp;<EM>'D'</EM>,&nbsp;new_balance);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>ELSE</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>RAISE</STRONG>&nbsp;insufficient_funds;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>IF</STRONG>;<BR>&nbsp;&nbsp;<STRONG>EXCEPTION</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHEN</STRONG>&nbsp;NO_DATA_FOUND&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;<EM>'Bad&nbsp;account&nbsp;number'</EM>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHEN</STRONG>&nbsp;insufficient_funds&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;<EM>'Insufficient&nbsp;funds'</EM>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>WHEN</STRONG>&nbsp;<STRONG>OTHERS</STRONG>&nbsp;<STRONG>THEN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_status&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;SUBSTR(<STRONG>SQLERRM</STRONG>,&nbsp;1,&nbsp;70);<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;debit_account;<BR><STRONG>END</STRONG>&nbsp;bank_transactions; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>在这个包中,我们没有使用初始化部分。 </P>
                        <P class=title1>六、包中私有项和公有项</P>
                        <P>再看一下包emp_actions。包体声明了一个名为number_hired的变量,它被初始化为零。与在包说明中声明的内容不同,包体中的内容只局限于在当前包内使用。因此,在包外的PL/SQL代码就不能引用变量number_hired,这样的内容就是私有的。 
                        </P>
                        <P>但是,在emp_actions的说明中声明的内容,如异常invalid_salary,它对包外的程序来说就是可见的。因此,任何PL/SQL代码都可以访问它。这样的内容就是公有的。 
                        </P>
                        <P>当我们必须通过一个会话或跨事务来维护一些内容时,就需要把它们放在包体的声明部分。例如,number_hired的值在同一个会话中会被不断的更新。当会话结束时,这个值就会丢失。 
                        </P>
                        <P>如果我们必须把某些内容声明为公有的,就要把它们放在包的说明中。例如,声明在包bank_transactions中的常量minimum_balance就可以被广泛地使用。 
                        </P>
                        <P class=title1>七、重载包级子程序</P>
                        <P>PL/SQL允许两个或多个包级子程序拥有相同的名称。当我们想让一个子程序接受类型不同的相似的参数集合时,这个功能就很有效。例如,下面的包就定义了两个名为journalize过程: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;journal_entries&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;journalize(amount&nbsp;<STRONG>REAL</STRONG>,&nbsp;trans_date&nbsp;<STRONG>VARCHAR2</STRONG>);<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;journalize(amount&nbsp;<STRONG>REAL</STRONG>,&nbsp;trans_date&nbsp;INT);<BR><STRONG>END</STRONG>&nbsp;journal_entries;<BR><BR><STRONG>CREATE</STRONG>&nbsp;<STRONG>PACKAGE</STRONG>&nbsp;<STRONG>BODY</STRONG>&nbsp;journal_entries&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;...<BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;journalize(amount&nbsp;<STRONG>REAL</STRONG>,&nbsp;trans_date&nbsp;<STRONG>VARCHAR2</STRONG>)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;journal<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(amount,&nbsp;TO_DATE(trans_date,&nbsp;<EM>'DD-MON-YYYY'</EM>));<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;journalize;<BR><BR>&nbsp;&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;journalize(amount&nbsp;<STRONG>REAL</STRONG>,&nbsp;trans_date&nbsp;INT)&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;<STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>INSERT</STRONG>&nbsp;<STRONG>INTO</STRONG>&nbsp;journal<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>VALUES</STRONG>&nbsp;(amount,&nbsp;TO_DATE(trans_date,&nbsp;<EM>'J'</EM>));<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;journalize;<BR><STRONG>END</STRONG>&nbsp;journal_entries; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>第一个过程接受一个字符串trans_date,而第二个过程接受一个数字类型trans_date。每个过程都对数据进行了适当的处理操作。 
                        </P>
                        <P class=title1>八、包STANDARD是如何定义PL/SQL环境的</P>
                        <P>STANDARD包定义了PL/SQL环境。这个包的说明部分定义了全局类型、异常和子程序,这些内容对PL/SQL程序来说都是可用的。例如,STANDARD包声明了能返回一个数字的绝对值的ABS函数: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FUNCTION</STRONG>&nbsp;ABS&nbsp;(n&nbsp;<STRONG>NUMBER</STRONG>)&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>NUMBER</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>包STANDARD的内容对应用程序是可见的。我们不需要在引用这些内容的前面加限定修饰词。例如,我们可以从数据库触发器、存储子程序、Oracle工具或3GL应用程序中直接调用ABS: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>abs_diff&nbsp;:=&nbsp;ABS(x&nbsp;-&nbsp;y); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>如果我们在PL/SQL中重新声明了ABS,我们的本地声明就会覆盖掉全局声明。但是,我们仍然可以通过添加限定修饰词来引用内部函数ABS: 
                        </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap>abs_diff&nbsp;:=&nbsp;STANDARD.ABS(x&nbsp;-&nbsp;y); 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>大多数的内部函数都被重载了。例如,包STANDARD包含了下面几种声明:</P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>FUNCTION</STRONG>&nbsp;TO_CHAR&nbsp;(right&nbsp;<STRONG>DATE</STRONG>)&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>VARCHAR2</STRONG>;<BR><STRONG>FUNCTION</STRONG>&nbsp;TO_CHAR&nbsp;(left&nbsp;<STRONG>NUMBER</STRONG>)&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>VARCHAR2</STRONG>;<BR><STRONG>FUNCTION</STRONG>&nbsp;TO_CHAR&nbsp;(left&nbsp;<STRONG>DATE</STRONG>,&nbsp;right&nbsp;<STRONG>VARCHAR2</STRONG>)&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>VARCHAR2</STRONG>;<BR><STRONG>FUNCTION</STRONG>&nbsp;TO_CHAR&nbsp;(left&nbsp;<STRONG>NUMBER</STRONG>,&nbsp;right&nbsp;<STRONG>VARCHAR2</STRONG>)&nbsp;<STRONG>RETURN</STRONG>&nbsp;<STRONG>VARCHAR2</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>PL/SQL会按照形参与实参的个数和类型来解析对函数TO_CHAR的调用。 </P>
                        <P class=title1>九、系统包一览</P>
                        <P>Oracle和各种Oracle工具都提供了系统包来帮助我们建立基于PL/SQL的应用程序。例如,Oracle提供了许多工具包,下面介绍一下其中比较典型的包。 
                        </P>
                        <P class=title2>1、关于DBMS_ALERT包</P>
                        <P>DBMS_ALERT能让数据库触发器在特定的数据库值发生变化时向应用程序发送报警。报警是基于事务的并且是异步的(也就是它们的操作与定时机制无关)。例如,当新的股票和债券上市时公司就可以通过这个包更新来他的投资总额。 
                        </P>
                        <P class=title2>2、关于DBMS_OUTPUT包</P>
                        <P>包DBMS_OUTPUT能让我们显示来自PL/SQL块和子程序中的输出内容,这样就会很容易地进行测试和调试。过程put_line能把信息输出到SGA的一个缓存中。我们可以通过调用过程get_line或在SQL*Plus中设置SERVEROUTPUT 
                        ON就能显示这些信息。假设我们创建了下面的存储过程: </P>
                        <BLOCKQUOTE>
                          <TABLE>
                            <TBODY>
                            <TR>
                              <TD 
                                noWrap><STRONG>CREATE</STRONG>&nbsp;<STRONG>PROCEDURE</STRONG>&nbsp;calc_payroll(payroll&nbsp;<STRONG>OUT</STRONG>&nbsp;<STRONG>NUMBER</STRONG>)&nbsp;<STRONG>AS</STRONG><BR>&nbsp;&nbsp;<STRONG>CURSOR</STRONG>&nbsp;c1&nbsp;<STRONG>IS</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>SELECT</STRONG>&nbsp;sal,&nbsp;comm<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>FROM</STRONG>&nbsp;emp;<BR><STRONG>BEGIN</STRONG><BR>&nbsp;&nbsp;payroll&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;0;<BR><BR>&nbsp;&nbsp;<STRONG>FOR</STRONG>&nbsp;c1rec&nbsp;<STRONG>IN</STRONG>&nbsp;c1&nbsp;<STRONG>LOOP</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;c1rec.comm&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;NVL(c1rec.comm,&nbsp;0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;payroll&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;payroll&nbsp;+&nbsp;c1rec.sal&nbsp;+&nbsp;c1rec.comm;<BR>&nbsp;&nbsp;<STRONG>END</STRONG>&nbsp;<STRONG>LOOP</STRONG>;<BR><BR>&nbsp;&nbsp;<EM>/*&nbsp;Display&nbsp;debug&nbsp;info.&nbsp;*/</EM><BR>&nbsp;&nbsp;DBMS_OUTPUT.put_line(<EM>'Value&nbsp;of&nbsp;payroll:&nbsp;'</EM>&nbsp;||&nbsp;TO_CHAR(payroll));<BR><STRONG>END</STRONG>; 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P>使用下面的命令时,SQL*Plus就能显示出payroll的值: </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;VARIABLE&nbsp;num&nbsp;<STRONG>NUMBER</STRONG><BR><STRONG>SQL</STRONG>&gt;&nbsp;CALL&nbsp;calc_payroll(:num);<BR>Value&nbsp;of&nbsp;payroll:&nbsp;31225 
                              </TD></TR></TBODY></TABLE></BLOCKQUOTE>
                        <P class=title2>3、关于DBMS_PIPE包</P>
                        <P>包DBMS_PIPE允许不同的会话通过命名管道来进行通信(管道就是一块内存区域,进程使用这个区域把消息传递给另外一个进程)。我们可以使用过程pack_message和send_message把消息封装到一个管道,然后把消息发送到同一个实例中的另一个会话中。 
                        </P>
                        <P>管道的另一个终端,我们可以使用过程recieve_message和unpack_message来接受并打开要读取的消息。命名管道在很多地方都很有用。例如,我们可以用C语言编写一个收集信息的程序,然后把信息通过管道传递给存储过程。</P>
                        <P class=title2>4、关于UTL_FILE包</P>
                        <P>包UTL_FILE能让我们的PL/SQL程序读写操作系统(OS)文本文件。它提供了标准的OS流文件I/O,包括open、put、get和close操作。 
                        </P>
                        <P>当我们想要读写文件的时候,我们可以

⌨️ 快捷键说明

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