友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
富士康小说网 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

SQL 21日自学通(V3.0)(PDF格式)-第51部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!





激活 



                                                                                       394 


…………………………………………………………Page 395……………………………………………………………

SQL 21  日自学通(V1。0)                                                                翻译人     笨猪 



     如果在这个语句块运行的过程中产生的异常  用户将会看到 



INPUT 



     SQL》 @block1 



     ERROR:    DIVISOR  IS  ZERO。    SEE  YOUR  DBA。 



     PL/SQL procedure successfully pleted。 



     是不是这样的错误信息比下边的错误信息更友好 



输入/输出 



     SQL》 @block1 



     begin 



     * 



     ERROR at line 1: 



     ORA…01476: divisor is equal to zero 



     ORA…06512: at line 20 



在 PL/SQL  中的事务控制 



     在第 11 天中的 事务控制  中 我们已经讨论了事务控制命令 MIT                                     ROLLBACK 



SAVEPOINT      这些命令可以让程序员在在事务向数据库中进行写操作时加以控制  在多数 



时候所进行的操作是需要撤消 



语法 



     BEGIN 



         DECLARE 



           。。。 



         BEGIN 



             statements。。。 



             IF  condition  THEN 



                 MIT; 



             ELSE 



                 ROLLBACK; 



             END  IF; 



                                                                                           395 


…………………………………………………………Page 396……………………………………………………………

SQL 21  日自学通(V1。0)                                                  翻译人    笨猪 



            。。。 



        EXCEPTION 



            。。。 



        END; 



    END; 



    PL/SQL  的一个好处就是你可以用自动地执行事务控制命令来代替对大型事务的不断 



监控— — 这是非常单调和乏味的 



让所有的事在一起工作 



    到目前为止 我们已经介绍了 PL/SQL              你已经熟悉了它所支持的数据类型以及 PL/SQL 



语句块的主要特性          你已经知道了如何定义一个局部变量  常量和指针  你也已经知道了 



如何在一个 PROCDURE  部分          指针的操作部分和异常部分嵌入 SQL  语句                 当指针在使用 



时  你应该清楚地知道如何在异常部分捕获它                     现在你已经可以使用 BEGIN              END   语 



句块来进行了实际工作  在今天的结束部分  你将会彻底明白 PL/SQL                           语句块之间的相同 



关系 



示例表及数据 



    在我们创建的 PL/SQL 语句块中使用两个表  PAYMENT_TABLE 确定了一个客户                           她 



/他的付款是多少         应得的总数是多少  PAY_STATUS_TABLE  最初实际上没有任何数据 



数据将会依据 PAYMENT_TABLE 中的特定条件插入到 PAY_STATUS_TABLE 表中 



输入 



    SQL》 select * from payment_table; 



输出 



CUSTOMER       PAYMENT      TOTAL_DUE 



ABC            90。50        150。99 



AAA            79。00        79。00 



BBB            950。00       1000。00 



CCC            27。50        27。50 



DDD            350。00       500。95 



EEE            67。89        67。89 



                                                                            396 


…………………………………………………………Page 397……………………………………………………………

SQL 21  日自学通(V1。0)                                                             翻译人     笨猪 



FFF              555。55          455。55 



GGG              122。36          122。36 



HHH              26。75           0。00 



输入 



     SQL》 describe pay_status_table 



输出 



       Name               Null?             Type 



       CUST_ID            NOT    NULL       CHAR(3) 



       STATUS             NOT    NULL       VARCHAR2(15) 



       AMT_OWED                             NUMBER(8;2) 



       AMT_CREDIT                           NUMBER(8;2) 



分析 



     DESCRIBE 是一个 ORACLE SQL            它可以不通过查询数据字典就可以显示一个表的结 



构  它与其它的 ORACLE SQL*PLUS 命令将会在第 20 天                        SQL*PLUS     中提到 



一个简单的 PL/SQL 语句块 



     这个 PL/SQL  的脚本内容如下所示 



输入 



     set serveroutput on 



     BEGIN 



         DECLARE 



             AmtZero  EXCEPTION; 



             cCustId  payment_table。cust_id%TYPE; 



             fPayment  payment_table。payment%TYPE; 



             fTotalDue  payment_table。total_due%TYPE; 



             cursor  payment_cursor  is 



                 select  cust_id;  payment;  total_due 



                 from  payment_table; 



             fOverPaid  number(8;2); 



             fUnderPaid  number(8;2); 



         BEGIN 



                                                                                        397 


…………………………………………………………Page 398……………………………………………………………

SQL 21  日自学通(V1。0)                                                                                                   翻译人        笨猪 



               open  payment_cursor; 



               loop 



                   fetch  payment_cursor  into 



                       cCustId;  fPayment;  fTotalDue; 



                   exit  when  payment_cursor%NOTFOUND; 



                   if  (  fTotalDue  =  0  )  then 



                       raise  AmtZero; 



                   end  if; 



                   if  (  fPayment  》  fTotalDue  )  then 



                       fOverPaid  :=  fPayment   fTotalDue; 



                       insert  into  pay_status_table  (cust_id;  status;  amt_credit) 



                       values  (cCustId;  'Over  Paid';  fOverPaid); 



                   elsif  (  fPayment  《  fTotalDue  )  then 



                       fUnderPaid  :=  fTotalDue   fPayment; 



                       insert  into  pay_status_table  (cust_id;  status;  amt_owed) 



                       values  (cCustId;  'Still  Owes';  fUnderPaid); 



                   else 



                       insert  into  pay_status_table 



                       values  (cCustId;  'Paid  in  Full';  null;  null); 



                   end  if; 



               end  loop; 



               close  payment_cursor; 



           EXCEPTION 



               when  AmtZero  then 



           DBMS_OUTPUT。put_line('ERROR: amount is Zero。 See your supervisor。'); 



               when  OTHERS  then 



           DBMS_OUTPUT。put_line('ERROR: unknown error。 See the DBA'); 



           END; 



       END; 



       / 



                                                                                                                                  398 


…………………………………………………………Page 399……………………………………………………………

SQL 21  日自学通(V1。0)                                                   翻译人    笨猪 



分析 



    DECLARE 部分定义了六个局部变量 与被称为payment_cursor 指针一样 PROCEDURE 



从第二个 BEGIN 语句开始并先打开了这个游标并开始循环                         而 FETCH 命令则将当前指针 



所指向的记录的内容存入在 DECLARE               部分定义的变量中           当在指针中发现记录以后  语 



句会将客户的支付与他应付的总数进行比较                      根据支付的的数量来计算已付款的人数和未 



付款的人数       然后将计算过的数据插入到 PAY_STATUS_TABLE  表中                   当循环终止以后 



关闭指针  异常用于处理在这一部分可以发生的错误 



    现在    我们来运行一个这个脚本看一个他的结果 



    INPUT: 



    SQL》 @block1 



    OUTPUT: 



    Input truncated to 1 characters 



    ERROR: amount is Zero。 See your supervisor。 



    PL/SQL procedure successfully pleted。 



    现在看来你在应得总数上有一个数值是不正确的                        你应该修正这个数量然后再运行脚 



本 



输入/输出 



    SQL》 update payment_table  set total_due = 26。75 where cust_id = 'HHH'; 



    1 row updated。 



    SQL》 mit; 



    mit plete。 



    SQL》 truncate table pay_status_table; 



    Table truncated。 



注  在上例中我们清除了 pay_status_table         中的内容  在下一次运行这个语句块时表将会被 



   重新写入       你也许会想把清除语句也加入到语句块中吧 



输入/输出 



    SQL》 @block1 



    Input truncated to 1 characters 



    PL/SQL procedure successfully pleted。 



                                                                             399 


…………………………………………………………Page 400……………………………………………………………

SQL 21  日自学通(V1。0)                                                翻译人    笨猪 



    现在你可以对 PAY_STATUS_TABLE 表执行 SELECT  语句             看一下每一个客户的支付 



情况 



输入/输出 



    SQL》 select * from pay_status_table order by status; 



        CUSTOMER    STATUS    AMT_OWED       AMT_CREDIT 



        FFF                   OverPaid       100。00 



       AAA                    PaidinFull 



        CCC                   PaidinFull 



        EEE                   PaidinFull 



        GGG                   PaidinFull 



        HHH                   PaidinFull 



       ABC                    StillOwes      60。49 



        DDD                   StillOwes      150。95 



        BBB                   StillOwes      50。00 



分析 



    从 PAYMENT_TABLE  获得的数据中有一行被插入到了 PAY_STATUS_TABLE  表中 



如果用户的付款金额比应付金额更多                 那么差额将会被输入到 AMT_CREDIT            列中  如果 



用户的支付金额少于应付金额  那么将会在 AMT_OWED                    中输入一个信息  如果客户已经 



全部支付完毕       那么这两列中就不会有任何数据 



又一个程序 



    在这个例子中使用的表叫 PAY_TABLE 



输入 



    SQL》 desc pay_table 



输出 



    Name            Null?          Type 



    NAME            NOT NULL       VARCHAR2(20) 



    PAY_TYPE        NOT NULL       VARCHAR2(8) 



    PAY_RATE        NOT NULL       NUMBER(8;2) 



    EFF_DATE        NOT NULL       DATE 



    PREV_PAY                       NUMBER(8;2) 



    先来看一下数据 



                                                                         400 


…………………………………………………………Page 401……………………………………………………………

SQL 21  日自学通(V1。0)                                                             翻译人     笨猪 



输入 



     SQL》 select * from pay_table order by pay_type; pay_rate desc; 



输出 



NAME                       PAY_TYPE         PAY_RATE        EFF_DATE PREV_PAY 



SANDRA SAMUELS             HOURLY                    12。50  01…JAN…97 



ROBERT BOBAY               HOURLY                    11。50  15…MAY…96 



KEITH JONES                HOURLY                    10。00  31…OCT…96 



SUSAN WILLIAMS             HOURLY                     9。75  01…MAY…97 



CHRISSY ZOES               SALARY                 50000。00  01…JAN…97 



CLODE EVANS                SALARY                 42150。00  01…MAR…97 



JOHN SMITH                 SALARY                 35000。00  15…JUN…96 



KEVIN TROLLBERG            SALARY                 27500。00  15…JUN…96 



     现实情况        由于销售情况很好  你需要给为你工作的时间超过了六个月的个人增加薪 



金    符合条件的钟点工的薪金增加 4%                    而符全条件的雇员的薪金需要增加 5% 



     今天的日期是 



     输入/输出 



     SQL》 select sysdate from dual 



     SYSDATE 



     20…MAY…97 



     在对下边的 PL/SQL         语句块进行检查之前              我们要对 PAY_TABLE  表进行手工的选择 



以找出都有哪些人需要增加薪金 



输入 



     SQL》 select name; pay_type; pay_rate; eff_date; 



         2                  'YES'  due 



         3    from  pay_table 



         4    where  eff_date  《  sysdate   180 



         5    UNION  ALL 



         6    select  name;  pay_type;  pay_rate;  eff_date; 



         7                  'No'  due 



         8    from  pay_table 



         9    where  eff_date  》=  sysdate   180 



                                                                                        401 


…………………………………………………………Page 402……………………………………………………………

SQL 21  日自学通(V1。0)                                                                        翻译人      笨猪 



       10    order  by  2;  3  desc; 



输出 



   NAME                         PAY_TYPE          PAY_RATE          EFF_DATE          DUE 



    SANDRA SAMUELS              HOURLY                      12。50   01…JAN…97         No 



    ROBERT BOBAY                HOURLY                      11。50   15…MAY…96         YES 



    KEITH JONES                 HOURLY                      10。00   31…OCT…96         YES 



    SUSAN WILLIAMS              HOURLY                       9。75   01…MAY…97           No 



    CHRISSY ZOES                SALARY                   50000。00   01…JAN…97         No 



    CLODE EVANS                 SALARY                   42150。00   01…MAR…97         No 



    JOHN SMITH                  SALARY                   35000。00   15…JUN…96         YES 



    KEVIN TROLLBERG             SALARY                   27500。00   15…JUN…96         YES 



     DUE 列的内容是确定每一个人是否有增加工资的资格                                       下边是 PL/SQL  的脚本 



输入 



     set serveroutput on 



     BEGIN 



         DECLARE 



             UnknownPayType  exception; 



             cursor  pay_cursor  is 



                 select  name;  pay_type;  pay_rate;  eff_date; 



                               sysdate;  rowid 



                 from  pay_table; 



             IndRec  pay_cursor%ROWTYPE; 



             cOldDate  date; 



             fNewPay  number(8;2); 



         BEGIN 



             open  pay_cursor; 



             loop 



             fetch  pay_cursor  into  IndRec; 



             exit  when  pay_cursor%NOTFOUND; 



             cOldDate  :=  sysdate   180; 



         if (IndRec。pay_type = 'SALARY') then 



                                                                                                     402 


…………………………………………………………Page 403……………………………………………………………

SQL 21  日自学通(V1。0)                                                                                        翻译人        笨猪 



                  fNewPay  :=  IndRec。pay_rate  *  1。05; 



              elsif  (IndRec。pay_type  =  'HOURLY')  then 



                  fNewPay  :=  IndRec。pay_rate  *  1。04; 



              else 



                  raise  UnknownPayType; 



              end  if; 



              if  (IndRec。eff_date  《  cOldDate)  then 



                  update  pay_table 



                  set  pay_rate  =  fNewPay; 



                          prev_pay  =  IndRec。pay_rate; 



                          eff_date  =  IndRec。sysdate 



                  where  rowid  =  IndRec。rowid; 



                  mit; 



              end  if; 



              end  loop; 



              close  pay_cu
返回目录 上一页 下一页 回到顶部 9 9
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!