亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

PL/SQL 塊的學習(精華)

2024-07-21 02:45:11
字體:
來源:轉載
供稿:網友
PL/SQL塊
  declare
  begin
   --SQL語句
   --直接寫的SQL語句(DML/TCL)
   --間接寫execute immediate <DDL/DCL命令字符串>
   --select 語句
        <1>必須帶有into子句
         select empno into eno from emp
           where empno =7369;
        <2>只能查到一行**********
        <3>字段個數必須和變量的個數一致
  exception
    --異常
    when <異常名字> then --特定異常
        <處理語句>
    when others then  --所有異常都可捕獲
        <處理語句>   
  end;
<例子>
   編寫程序 向DEPT表中插入一條記錄,
   從鍵盤輸入數據,如果
      數據類型輸入錯誤要有提示
      無法插入記錄 也要有提示
      只能輸入正數,如果有負數提示
   declare
    n number;
    no dept.deptno%type;
    nm dept.dname%type;
    lc dept.loc%type;
    exp exception;   --異常的變量
    exp1 exception;
    num number:=0;  --計數器
    PRagma exception_init(exp,-1); --預定義語句
         --(-1錯誤和異常變量關聯)
    pragma exception_init(exp1,-1476);
    e1 exception; --自定義異常變量
   begin
    --輸入值
     no := '&編號';
     num := num + 1;
     if no < 0 then
        raise e1;    --自定義異常的引發
     end if;
     nm := '&名稱';
     num := num +1;
     lc := '&地址';  
     num := num +1;
     n := 10 /0;     
     insert into dept values (no,nm,lc);
     num := num +1;
     commit;
   exception
     --自定義異常
     when e1 then
        dbms_output.put_line('編號不能為負數');
     --數據類型不對
     when value_error then
        if num =0 then  
         dbms_output.put_line('編號數據類型不對');
        elsif num = 1 then
         dbms_output.put_line('名稱數據類型不對');
        elsif num =2 then
         dbms_output.put_line('地址數據類型不對');
        end if;
        rollback;
     --主鍵沖突
     when exp then
         --sqlcode全局變量 異常錯誤號
         --sqlerrm全局變量 異常的文字信息  
         --dbms_output.put_line('異常的編號:'||sqlcode);
         --dbms_output.put_line('異常的內容:'||sqlerrm);
         --dbms_output.put_line('編號已存在') ;
         rollback;
     --非預定義異常(關聯錯誤號)
     when exp1 then
         --dbms_output.put_line('0做了除數') ;
         raise_application_error(-20001,'0做了除數'); --引起一個自定義的錯誤
         --預先保留-20001 到 -29999編號
         rollback;
     --其他的異常
     when others then
         dbms_output.put_line('異常的編號:'||sqlcode);
         dbms_output.put_line('異常的內容:'||sqlerrm);
        -- dbms_output.put_line('出現錯誤');
         rollback;
   end;  
--    insert into dept values (40,'asdf','asdf');
<簡單的做法>
  --存放異常的
   create table save_exp(
      bh number,
      wz varchar2(1000)
   );
   declare
    no dept.deptno%type;
    nm dept.dname%type;
    lc dept.loc%type;
    errno number;
    errtext varchar2(1000);
   begin
     no := '&編號';
     nm := '&名稱';
     lc := '&地址';
  
     insert into dept values (no,nm,lc);
     commit;
   exception
    when others then
      rollback;
      errno := sqlcode;
      errtext := sqlerrm;       
      insert into save_exp values (errno,errtext);
      commit;
   end;
<游標>  內存中的一塊區域,存放的是select 的結果
   
   1。 隱式游標
     單條sql語句所產生的結果集合
       用關鍵字SQL表示隱式游標
        4個屬性 %rowcount  影響的記錄的行數  整數
                %found     影響到了記錄 true
                %notfound  沒有影響到記錄 true
                %isopen    是否打開  布爾值 永遠是false
         多條sql語句 隱式游標SQL永遠指的是最后一條sql語句的結果
         主要使用在update 和 delete語句上      
   2。 顯式游標
      select語句上 使用顯式游標
      明確能訪問結果集
         for循環游標
         參數游標
           解決多行記錄的查詢問題
         fetch游標
顯示游標
   需要明確定義
   (1)FOR循環游標 (常用的一種游標)
--<1>定義游標
--<2>定義游標變量
--<3>使用for循環來使用這個游標
  --前向游標 只能往一個方向走
  --效率很高
      declare
        --類型定義
        cursor cc is select empno,ename,job,sal
         from emp where job = 'MANAGER';
        --定義一個游標變量
        ccrec cc%rowtype;

      begin
         --for循環
         for ccrec in cc loop
            dbms_output.put_line(ccrec.empno||'-'||ccrec.ename||'-'||ccrec.job||'-'||ccrec.sal);
         end loop;
       
      end;
   (2) fetch游標
     --使用的時候 必須要明確的打開和關閉
      declare
        --類型定義
        cursor cc is select empno,ename,job,sal
         from emp where job = 'MANAGER';
        --定義一個游標變量
        ccrec cc%rowtype;

      begin
        --打開游標
         open cc;
        --loop循環
         loop
            --提取一行數據到ccrec中
            fetch cc into ccrec;         
            --判斷是否提取到值,沒取到值就退出
            --取到值cc%notfound 是false
            --取不到值cc%notfound 是true
            exit when cc%notfound;
            dbms_output.put_line(ccrec.empno||'-'||ccrec.ename||'-'||ccrec.job||'-'||ccrec.sal);            
         end loop;
        --關閉
         close cc;  
       
      end;
  游標的屬性4種
       %notfound  fetch是否提到數據 沒有true 提到false
       %found      fetch是否提到數據 有true 沒提到false
       %rowcount  已經取出的記錄的條數
       %isopen    布爾值 游標是否打開
declare
        --類型定義
        cursor cc is select empno,ename,job,sal
         from emp where job = 'MANAGER';
        --定義一個游標變量
        ccrec cc%rowtype;
   
      begin
        --打開游標
         open cc;
        --loop循環
         loop
            --提取一行數據到ccrec中
            fetch cc into ccrec;         
            --判斷是否提取到值,沒取到值就退出
            --取到值cc%notfound 是false
            --取不到值cc%notfound 是true
            exit when (cc%notfound or cc%rowcount =3);
            dbms_output.put_line(cc%rowcount||'-'||ccrec.empno||'-'||ccrec.ename||'-'||ccrec.job||'-'||ccrec.sal);            
         end loop;
        --關閉
         close cc;  
       
      end;
<例子>
  declare
       cursor cc is select dept.dname,
        emp.ename,emp.sal from
         dept,emp where dept.deptno = emp.deptno;
       ccrec cc%rowtype;
  begin
      for ccrec in cc loop
      
       dbms_output.put_line(ccrec.dname||'-'||ccrec.ename||'-'||ccrec.sal);
      end loop;
   
  end;  
   (3)參數游標
按部門編號的順序輸出部門經理的名字
     declare
       --部門
       cursor c1 is select deptno from dept;
       --參數游標c2,定義參數的時候
       --只能指定類型,不能指定長度  
       --參數只能出現在select語句=號的右側
       cursor c2(no number,pjob varchar2) is select emp.* from emp
         where deptno = no and job=pjob;
    /*
       no = 10  pjob = 'MANAGER'
          select * from emp where deptno = 10 and job = 'MANAGER';   
     */
       c1rec c1%rowtype;
       c2rec c2%rowtype;
       --定義變量的時候要指定長度
       v_job varchar2(20);
     begin
       --部門
        for c1rec in c1 loop
          --參數在游標中使用
          for c2rec in c2(c1rec.deptno,'MANAGER') loop
            dbms_output.put_line(c1rec.deptno||'-'||c2rec.ename);
          end loop;
        end loop;
     end;
<綜合例子>
  求購買的商品包括了顧客"Dennis"所購買商品的顧客(姓名);**************
   思路:
      Dennis (A,B)
      別的顧客 (A,B,C) (A,C) (B,C)  C
  declare
   --Dennis所購買的商品
   cursor cdennis is select productid
         from purcase where customerid=(
           select customerid from
           customer where name = 'Dennis');
   --除Dennis以外的每個顧客
   cursor ccust is select customerid
        from customer where name <> 'Dennis';
   --每個顧客購買的商品
   cursor cprod(id varchar2) is
     select productid from purcase
          where customerid = id;
   j number ;
   i number;
   c1rec cdennis%rowtype;
   c2rec ccust%rowtype;
   c3rec cprod%rowtype;
   cname varchar2(10);
  begin
    --顧客循環
    for c2rec in ccust loop
     i:=0;
     j:=0;
     for c1rec in cdennis loop
        i := i + 1;
        
      --每個顧客買的東西
       for c3rec in cprod(c2rec.customerid) loop
           if (c3rec.productid = c1rec.productid) then
               j := j + 1;
           end if;
        end loop;   
      
     end loop;
                        
       if (i=j) then
        select name into cname from
           customer where customerid = c2rec.customerid;
        DBMS_output.put_line(cname);        
       end if;
    end loop;
  end;
  (4)引用游標/動態游標
        select語句是動態的
     declare
       --定義一個類型(ref cursor)弱類型    
       type cur is ref cursor;
         --強類型(返回的結果集有要求)
       type cur1 is ref cursor return emp%rowtype;
       --定義一個ref cursor類型的變量   
       cura cur;
       --
       c1rec emp%rowtype;
       c2rec dept%rowtype;
     begin
  DBMS_output.put_line('輸出員工')   ;       
       open cura for select * from emp;
       loop
         fetch cura into c1rec;   
         exit when cura%notfound;
         DBMS_output.put_line(c1rec.ename)   ;
       end loop ;
  DBMS_output.put_line('輸出部門')   ;
       open cura for select * from dept;
       loop
         fetch cura into c2rec;   
         exit when cura%notfound;
         DBMS_output.put_line(c2rec.dname)   ;
       end loop;  
       close cura;
    end;
>>>>>存儲過程和函數
  沒有名字的PL/SQL塊(匿名)
  有名字的PL/SQL塊(子程序-存儲過程和函數)
存儲過程
      create or replace procedure p1
      as
      begin
      exception
      end;
<最簡單的存儲過程>
       create or replace procedure p_jd
       as
         hello varchar2(20);  
       begin
        select 'Hello World' into hello from dual;
        dbms_output.put_line(hello);
       end;
執行存儲過程的方法
      <1> execute p_jd;     (SQL*PLUS中SQL>)
      <2> begin
           p_jd;
          end;  
帶參數的存儲過程
   --輸入參數in
   --不寫in的參數都是輸入參數
   --根據部門編號查員工姓名
    create or replace procedure p_getemp(no  number)
    as
      cursor c1 is select * from emp
       where deptno = no;
      c1rec c1%rowtype;
    begin
  --       no := 20; 輸入參數是不能賦值的
       for c1rec in c1 loop
        dbms_output.put_line(c1rec.ename);
       end loop;
    end;     
   --輸出參數out
   --根據部門編號查出部門的平均工資,返回平均工資的值
   -- in 輸入 (在procedure中是不能賦值的)
   --  out 輸出 (在procedure中是能賦值的)
-- 定義參數是不能指定長度的
--定義變量是必須指定長度的
    create or replace procedure p_getavgsal(no  number,avgsal out number)
    -- no   輸入參數
    -- avgsal  輸出參數
    as
     aa varchar2(10); --變量
    begin
       select avg(sal) into avgsal
       from emp where deptno = no;  
    end;     
    調用它只能使用PL/SQL塊
        declare
         av number;
        begin          
          p_getavgsal(10,av);
          dbms_output.put_line('平均工資:'||round(av,2));
        end;        
   --一個參數同時可以輸入,也可以輸出
   --輸入輸出參數
    create or replace procedure
    p_getavgsal(n in out number)
    as
    begin
       select avg(sal) into n
       from emp where deptno = n;  
    end;
    
   declare
         av number;
        begin          
          av  := 10;
          p_getavgsal(av);
          dbms_output.put_line('平均工資:'||round(av,2));
        end;        
  --帶多個參數的存儲過程
     create or replace procedure
      p_getM(no number,pjob varchar2) as
       --參數游標c2,定義參數的時候
       --只能指定類型,不能指定長度  
       --參數只能出現在select語句=號的右側
       cursor c2(no1 number,pjob1 varchar2) is select * from emp
         where deptno = no1 and job=pjob1;
       c2rec c2%rowtype;
       --定義變量的時候要指定長度
       v_job varchar2(20);
     begin
          --參數在游標中使用
          for c2rec in c2(no,pjob) loop
            dbms_output.put_line(c2rec.deptno||'-'||c2rec.ename);
          end loop;
     end;
   
    調用方法:execute p_getm(10,'MANAGER'); --按位置
   -- no = 10 , pjob = 'MANAGER'
           
      execute p_getm(pjob => 'MANAGER',no => 10);
   --按參數的名字 來傳值
  函數:
    必須要有返回值
    只能返回一個值
   
   --根據部門編號查出部門的平均工資,返回平均工資的值(利用函數)
    create or replace function
    f_getavgsal(no number)
    return number
    as
      avgsal number(7,2);
    begin
       select avg(sal) into avgsal
       from emp where deptno = no;
       --返回值
       return avgsal;   
    end;   
  
--帶輸出參數
--每個部門的平均工資和工資總額
--一個函數返回2個值
create or replace function
    f_getavgsal(no number,sumsal out number)
    return number
    as
      avgsal number(7,2);
    begin
       --平均工資
       select avg(sal) into avgsal
       from emp where deptno = no;
       --工資總額
       select sum(sal) into sumsal
       from emp where deptno = no;
       --返回值
       return avgsal;   
    end;     
  --調用方法
     <1>PL/SQL塊調用
      declare
       aa number;
      begin
        aa := f_getavgsal(10)  ;
        dbms_output.put_line(to_char(aa));
      end;  
    <2> SQL語句來調用(DML)
       select f_getavgsal(10) from dual;
       select deptno,f_getavgsal(deptno) from dept;
    <3>
       create or replace function f1
       return number
       as
         update emp set comm = 1000
          where job='CLERK';
         return sql%rowcount;
       end;
      --select語句是無法調用它的,因為其中含有修改語句


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/shenghuiping2001/archive/2009/12/30/5105949.aspx
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲成人免费在线视频| 国产精品精品一区二区三区午夜版| 欧美资源在线观看| 91深夜福利视频| 久久综合88中文色鬼| 丁香五六月婷婷久久激情| 国产suv精品一区二区三区88区| 久久久久久成人精品| 91精品视频播放| 亚洲大尺度美女在线| 久久亚洲精品一区二区| 欧美性理论片在线观看片免费| 国内精品久久久久影院 日本资源| 国产精品成人av在线| 欧美激情综合亚洲一二区| 国产主播在线一区| 国产精品九九九| 欧美亚洲成人xxx| 欧美激情影音先锋| 久久伊人精品一区二区三区| 久久躁日日躁aaaaxxxx| 在线免费看av不卡| 欧美在线视频观看免费网站| 久久视频国产精品免费视频在线| 国产精品欧美风情| 欧美日韩色婷婷| 日韩av在线资源| 2019亚洲男人天堂| 亚洲欧美制服第一页| 国产99视频精品免视看7| 国产精品视频久久| 亚洲成人xxx| 国产精品一区=区| 久久久久久亚洲| 亚洲欧美三级在线| 精品成人乱色一区二区| 久久精品91久久香蕉加勒比| 中文字幕久热精品在线视频| 国产在线观看精品| 日韩高清人体午夜| 国产精品一区二区久久精品| 亚洲999一在线观看www| 日韩中文字幕视频在线观看| 成人午夜小视频| 91超碰中文字幕久久精品| 久久全球大尺度高清视频| 日韩欧美a级成人黄色| 国产人妖伪娘一区91| 久久久久久久999精品视频| 91在线视频免费| 国产男女猛烈无遮挡91| 精品欧美一区二区三区| 国产欧美精品久久久| 成人在线激情视频| 777国产偷窥盗摄精品视频| 亚洲美女精品久久| 亚洲精品av在线播放| 成人免费观看49www在线观看| 4388成人网| 欧洲成人在线视频| 中文字幕亚洲一区二区三区五十路| 欧美极品美女视频网站在线观看免费| 一本色道久久88精品综合| 91精品国产综合久久男男| 亚洲老头同性xxxxx| 精品久久香蕉国产线看观看gif| 91高清视频免费| 国产精品爽爽爽爽爽爽在线观看| 最新亚洲国产精品| 久久久久久999| 亚洲影视中文字幕| 久久伊人91精品综合网站| 久久手机精品视频| 美女国内精品自产拍在线播放| 欧美日本啪啪无遮挡网站| 日本高清久久天堂| 91chinesevideo永久地址| 亚洲国产精品国自产拍av秋霞| 日韩精品在线观看一区二区| 国产成人精彩在线视频九色| 精品视频9999| 亚洲欧美日韩精品久久亚洲区| 亚洲精品美女在线| 国产精品美女www| 日韩精品在线观看一区二区| 精品久久久久久久久久国产| 77777少妇光屁股久久一区| 亚洲另类欧美自拍| 18一19gay欧美视频网站| 色哟哟入口国产精品| 国产精品久久久久久久久久久久久| 91在线观看免费高清| 日韩av在线播放资源| 亚洲人成网站在线播| 久久不射电影网| 最好看的2019的中文字幕视频| 成人免费观看a| 69精品小视频| 午夜精品福利在线观看| 不卡av在线网站| 国产精品爽爽爽爽爽爽在线观看| 欧美成人精品在线播放| 国产精品精品国产| 久青草国产97香蕉在线视频| 欧美精品激情视频| 久久精品亚洲精品| 91在线无精精品一区二区| 国产精品日韩在线一区| 在线视频中文亚洲| 亚洲网站视频福利| 精品国产31久久久久久| 亚洲91精品在线| 俺去亚洲欧洲欧美日韩| 伊人伊成久久人综合网站| 精品久久久视频| 97在线看免费观看视频在线观看| 国产在线观看一区二区三区| 亚洲18私人小影院| 日韩中文综合网| 中文字幕精品久久久久| 亚洲精品97久久| 中文字幕亚洲精品| 日韩小视频网址| 亚洲天堂第二页| 精品国产一区久久久| 色偷偷888欧美精品久久久| 成人中心免费视频| 欧美区在线播放| 亚洲精品日韩久久久| 中文字幕日韩精品有码视频| 亚洲国产日韩精品在线| 国产亚洲一区精品| 亚洲欧洲一区二区三区在线观看| 日韩av在线影视| 国产97在线观看| 国产精品伦子伦免费视频| 欧美电影院免费观看| 欧美成人合集magnet| 欧美日本精品在线| 国产97色在线| 中文字幕自拍vr一区二区三区| 中文字幕日韩在线视频| 97免费在线视频| 日本欧美中文字幕| 欧美午夜性色大片在线观看| 欧美精品在线播放| 国产日韩精品一区二区| 成人中文字幕+乱码+中文字幕| 免费av在线一区| 日韩欧美国产高清91| 91视频国产一区| 国产日韩精品电影| 91高潮精品免费porn| 91po在线观看91精品国产性色| 欧美电影在线观看网站| 亚洲视频在线观看网站| 亚洲欧美视频在线| 亚洲国产欧美一区二区丝袜黑人| 成人精品视频99在线观看免费| 国产91露脸中文字幕在线| 国产小视频国产精品| 国产精品高潮呻吟久久av黑人| 欧美激情啊啊啊| 深夜福利国产精品|