Oracle存儲過程

一、 存儲過程

1、定義
所謂存儲過程(Stored Procedure),就是一組用於完成特定數據庫功能的SQL語句集,該SQL語句集經過
編譯後存儲在數據庫系統中。在使用時候,用戶通過指定已經定義的存儲過程名字並給出相應的存儲過程參數
來調用並執行它,從而完成一個或一系列的數據庫操作。


2、存儲過程的創建
Oracle存儲過程包含三部分:過程聲明,執行過程部分,存儲過程異常。
(1)無參存儲過程語法

Sql代碼  收藏代碼


  1. create or replace procedure NoParPro  

  2.  as  //聲明  

  3.  ;  

  4.  begin // 執行  

  5.  ;  

  6.  exception//存儲過程異常  

  7.  ;  

  8.  end;  

 

(2)帶參存儲過程實例

Sql代碼  收藏代碼
  1. create or replace procedure queryempname(sfindno emp.empno%type)   
  2. as  
  3.    sName emp.ename%type;  
  4.    sjob emp.job%type;  
  5. begin  
  6.        ….  
  7. exception  
  8.        ….  
  9. end;  

 

(3)帶參數存儲過程含賦值方式

Sql代碼  收藏代碼
  1. create or replace procedure runbyparmeters    
  2.     (isal in emp.sal%type,   
  3.      sname out varchar,  
  4.      sjob in out varchar)  
  5.  as   
  6.     icount number;  
  7.  begin  
  8.       select count(*) into icount from emp where sal>isal and job=sjob;  
  9.       if icount=1 then  
  10.         ….  
  11.       else  
  12.        ….  
  13.      end if;  
  14. exception  
  15.      when too_many_rows then  
  16.      DBMS_OUTPUT.PUT_LINE(’返回值多於1行’);  
  17.      when others then  
  18.      DBMS_OUTPUT.PUT_LINE(’在RUNBYPARMETERS過程中出錯!’);  
  19. end;  

 

其中參數IN表示輸入參數,是參數的默認模式。
OUT表示返回值參數,類型可以使用任意Oracle中的合法類型。
OUT模式定義的參數只能在過程體內部賦值,表示該參數可以將某個值傳遞迴調用他的過程
IN OUT表示該參數可以向該過程中傳遞值,也可以將某個值傳出去。

 

(4)存儲過程中游標定義使用

Sql代碼  收藏代碼
  1. as //定義(遊標一個可以遍歷的結果集)   
  2. CURSOR cur_1 IS   
  3.   SELECT area_code,CMCODE,SUM(rmb_amt)/10000 rmb_amt_sn,  
  4.          SUM(usd_amt)/10000 usd_amt_sn   
  5.   FROM BGD_AREA_CM_M_BASE_T   
  6.   WHERE ym >= vs_ym_sn_beg   
  7.        AND ym <= vs_ym_sn_end   
  8.   GROUP BY area_code,CMCODE;   
  9.       
  10. begin //執行(常用For語句遍歷遊標)       
  11. FOR rec IN cur_1 LOOP   
  12.   UPDATE xxxxxxxxxxx_T   
  13.    SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn   
  14.    WHERE area_code = rec.area_code   
  15.    AND CMCODE = rec.CMCODE   
  16.    AND ym = is_ym;   
  17. END LOOP;  

(5)遊標的定義

Sql代碼  收藏代碼
  1. –顯示cursor的處理
  2. declare  
  3. —聲明cursor,創建和命名一個sql工作區
  4. cursor cursor_name is  
  5.     select real_name from account_hcz;
  6.     v_realname varchar2(20);
  7. begin 
  8.     open cursor_name;—打開cursor,執行sql語句產生的結果集
  9.     fetch cursor_name into v_realname;–提取cursor,提取結果集中的記錄
  10.     dbms_output.put_line(v_realname);
  11.     close cursor_name;–關閉cursor
  12. end;

3、在Oracle中對存儲過程的調用 

(1)過程調用方式一

Sql代碼  收藏代碼


  1. declare  

  2.       realsal emp.sal%type;  

  3.       realname varchar(40);  

  4.       realjob varchar(40);  

  5. begin   //過程調用開始  

  6.       realsal:=1100;  

  7.       realname:=;  

  8.       realjob:=’CLERK’;  

  9.       runbyparmeters(realsal,realname,realjob);--必須按順序  

  10.       DBMS_OUTPUT.PUT_LINE(REALNAME||’   ’||REALJOB);  

  11. END;  //過程調用結束  

 

(2)過程調用方式二

Sql代碼  收藏代碼


  1. declare  

  2.      realsal emp.sal%type;  

  3.      realname varchar(40);  

  4.      realjob varchar(40);  

  5. begin    //過程調用開始  

  6.      realsal:=1100;  

  7.      realname:=;  

  8.      realjob:=’CLERK’;  

  9.      --指定值對應變量順序可變  

  10.      runbyparmeters(sname=>realname,isal=>realsal,sjob=>realjob);           

  11.     DBMS_OUTPUT.PUT_LINE(REALNAME||’   ’||REALJOB);  

  12. END;  //過程調用結束    

 

(3)過程調用方式三(SQL命令行方式下)

Sql代碼  收藏代碼


  1. 1、SQL>exec  proc_emp(‘參數1’,‘參數2’);//無返回值過程調用  

  2. 2、SQL>var vsal number  

  3.      SQL> exec proc_emp (‘參數1’,:vsal);// 有返回值過程調用  

  4.       或者:call proc_emp (’參數1’,:vsal);// 有返回值過程調用  

 

4、JAVA調用Oracle存儲過程

 

(1)不帶輸出參數情況,過程名稱爲pro1,參數個數1個,數據類型爲整形數據

Java代碼  收藏代碼


  1. import  java.sql. * ;   

  2.  public   class  ProcedureNoArgs{      

  3.      public   static   void  main(String args[])  throws  Exception{   

  4.          //加載Oracle驅動    

  5.          DriverManager.registerDriver( new  oracle.jdbc.driver.OracleDriver());   

  6.          //獲得Oracle數據庫連接    

  7.          Connection conn = DriverManager.getConnection  

  8.           (”jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL”, sUsr, sPwd ” );  

  9.          //創建存儲過程的對象    

  10.          CallableStatement c = conn.divpareCall( ” {call pro1(?)} ” );        

  11.          //給Oracle存儲過程的參數設置值 ,將第一個參數的值設置成188    

  12.           c.setInt( 1 , 188 );        

  13.          // 執行Oracle存儲過程    

  14.           c.execute();   

  15.           conn.close();   

  16.      }    

  17. }  

 

(2)帶輸出參數的情況,過程名稱爲pro2,參數個數2個,數據類型爲整形數據,返回值爲整形類型。

Java代碼  收藏代碼


  1. import java.sql.*;   

  2. public class ProcedureWithArgs {     

  3.     public static void main(String args[]) throws Exception{       

  4.        //加載Oracle驅動   

  5.        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());   

  6.        //獲得Oracle數據庫連接   

  7.        Connection conn = DriverManager.getConnection  

  8.        (”jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL”, sUsr, sPwd ”);   

  9.        //創建Oracle存儲過程的對象,調用存儲過程   

  10.        CallableStatement c=conn.divpareCall(”{call pro2(?,?)}”);    

  11.        //給Oracle存儲過程的參數設置值 ,將第一個參數的值設置成188   

  12.        c.setInt(1,188);   

  13.        //註冊存儲過程的第二個參數   

  14.        c.registerOutParameter(2,java.sql.Types.INTEGER);      

  15.        c.execute(); //執行Oracle存儲過程   

  16.        //得到存儲過程的輸出參數值並打印出來  

  17.        System.out.println (c.getInt(2));   

  18.        conn.close();   

  19.     }   

  20. }    

 

二、 函數


1、基本語法規則

 

Sql代碼  收藏代碼


  1. create or replace function (Name in type, Name in type, …)   

  2.     return number   

  3.   is  

  4.     Result number;  

  5.  begin    

  6.     return (Result);  

  7.  end ;  

 

2、具體事例(查詢出empno=7935的sal值)

Sql代碼  收藏代碼


  1. create or replace function ret_emp_sal(v_ename varchar2)  

  2. return number  

  3.  is  

  4. v_sal number(7,2);  

  5.  begin  

  6. select nvl(sal,0) into v_sal from emp where lower(ename)=lower(v_ename);  

  7. return v_sal;  

  8.  end;  

 

3、函數調用:

Sql代碼  收藏代碼


  1. SQL> var vsla number  

  2. SQL> call ret_emp_sal(’7935’into :vsal;  

 

4、與存儲過程的區別

(1)返回值的區別,函數有1個返回值,而存儲過程是通過參數返回的,可以有多個或者沒有
(2)調用的區別,函數可以在查詢語句中直接調用,而存儲過程必須單獨調用.
(3)使用場景的區別,函數一般情況下是用來計算並返回一個計算結果
 而存儲過程一般是用來完成特定的數據操作(比如修改、插入數據庫表或執行某些DDL語句等等)

 

三、包
    包用於組合邏輯相關的過程和函數,它由包規範和包體兩個部分組成。包規範用於定義公用的常量、變量、過程
和函數,創建包規範可以使用CREATE PACKAGE命令,創建包體可以使用CREATE PACKAGE BODY.


1、創建包規範

Sql代碼  收藏代碼


  1. create package emp_pkg is  

  2.     procedure emp_update_ename(v_empno varchar2,v_ename varchar2);  

  3.     function emp_get_sal(v_empno varchar2) return number;  

  4. end;  

 

2、創建包體

Sql代碼  收藏代碼


  1. create or replace package body emp_pkg  

  2. is  

  3.     // 存儲過程  

  4. procedure emp_update_ename  

  5. (  

  6.     v_empno varchar2,  

  7.     v_ename varchar2  

  8. )  

  9. is  

  10.     vename varchar2(32);  

  11. begin   

  12.     update emp set ename=v_ename where empno=v_empno;  

  13.     commit;  

  14.     select ename into vename from emp where empno=v_empno;     

  15.     dbms_output.put_line(’僱員名稱:’||vename);      

  16. end;  

  17.    // 函數  

  18.    function emp_get_sal  

  19.    (  

  20.         v_empno varchar2  

  21.    )  

  22.    return number is  

  23.     vsal number(7,2);  

  24.    begin  

  25.     select sal into vsal from emp where empno=v_empno;  

  26.    return vsal;  

  27.    end;  

  28. nd;  

 

3、包調用
   在沒有創建包規範就創建包體,會失敗,要使用包,必須先創建包規範,然後在創建包體。
當要調用包的過程和函數時,在過程和函數的名稱前加上包名作爲前綴(包名.子程序名稱),
而如果要訪問其他方案的包時需要在包的名稱前加上方案的名稱(方案名稱.包名.子程序名稱)。


(1)調用包函數

Sql代碼  收藏代碼


  1. SQL> var vsla number  

  2. SQL> call emp_pkg.emp_get_sal(’7935’into :vsal;  

 

(2)調用包存儲過程

Sql代碼  收藏代碼


  1. SQL> exec emp_pkg.emp_update_ename(‘7935’,‘helong’);  


  1.   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章