1. 程式人生 > >oracle存儲過程相關整理

oracle存儲過程相關整理

NPU 語法 進行 scl pla 直接 logs 數據庫服務器 變量

存儲過程:

存儲過程是 SQL, PL/SQL, Java 語句的組合, 它使你能將執行商業規則的代碼從你的應用程序中移動到數據庫。這樣的結果就是,代碼存儲一次但是能夠被多個程序使用。是存放在數據庫服務器上的SQL語句塊,其效率高於同等SQL語句6-10倍

下面通過例子讓你了解存儲過程對數據的增刪查改(對Oracle中的emp操作)

一、Oracle存儲過程語法:

Create [or replace] procedure 存儲過程名稱 (輸入參數或輸出參數)]as

變量

Begin

執行主體

End;

二、IN, OUT , IN OUT 用來修飾參數。

IN 表示這個變量必須被調用者賦值然後傳入到 PROCEDURE 進行處理。

OUT 表示 PRCEDURE 通過這個變量將值傳回給調用者。

IN OUT 則是這兩種的組合。

三、執行存儲過程方式:

1、Call 存儲過程名稱(參數);

2、Execute 存儲過程名稱(參數);

註意:在oracle 數據庫中,call命令任何窗口都能使用,但是execute只能在命令窗口使用,否則會報無效的SQL語句的異常。

四、在存儲過程中需要註意事項:

1、在oracle數據庫存儲過程中,表別名不能用as

2、在oracle數據庫存儲過程中,select某一字段時,後面必須緊跟into,如果select整個記錄則必須使用遊標處理

3、在使用select....into....時必須保證數據庫有該數據,否則報”no data found”異常

4、在存儲過程中,別名不能和字段名相同,否則雖然編譯能通過,但是運行結果會報錯

五、存儲過程基本語法

 1 --案例一:無參存儲過程
 2 --1.創建結構
 3 CREATE PROCEDURE procedureName--存儲過程名字
 4   AS                          --as可替換成 is 
 5     --聲明變量
 6   BEGIN
 7     --執行主體
 8 END;
 9 
10 --2.案例
11 create or replace procedure firstPro is      
12 begin  
13   dbms_output.put_line(
Hello World);--打印輸出 14 exception --存儲過程異常 15 WHEN OTHERS THEN 16 ROLLBACK; 17 end firstPro; 18 19 --3.數據庫調用存儲過程:執行結果:output: Hello World 20 --(21) begin-end 21 begin 22 firstPro(); 23 end; 24 --(22)call 25 call firstPro(); 26 27 --4.刪除存儲過程 28 drop procedure firstPro;
 1 --案例二:帶參存儲過程(in:入參)
 2 --1.案例
 3 create or replace procedure secondPro(num in number) as
 4 begin
 5   dbms_output.put_line(The input num is :||num);
 6 end;
 7 --2.調用
 8 --(21)
 9 call secondPro(4);
10 --(22)
11 begin
12   secondPro(7);
13 end;
14 --(23)
15 declare
16   n number;
17 begin
18   n := 1;
19   secondPro(num=>n);
20 end;
21 --or
22 Begin
23   secondPro(num=>1);
24 end;
25 --備註:=> 是 Oracle 中調用 存儲過程的時候, 指定 參數名進行調用
26 --一般如果是按順序填寫參數的時候,是不需要用=>符號的,
27 --但是Oracle可以讓你在調用的時候,指定"參數名稱=>參數值", 這樣就可以不按參數的順序進行調用.
28 -- => 前面的變量為存儲過程的“形參”且必須於存儲過程中定義的一致,而=>後的參數為“實際參數”。
 1 --案例三:存儲過程:聲明變量
 2 --1.案例
 3 CREATE OR REPLACE procedure thirdPro  
 4   is  
 5     n_start   number;  
 6     n_end   number; 
 7     count_num number;
 8     use_time number;
 9   begin  
10     n_start:=dbms_utility.get_time;
11     dbms_output.put_line(This   statement   start  time : || n_start );
12     --查看oracle數據庫版本
13     SELECT count(*) into count_num FROM v$version;
14     n_end:=dbms_utility.get_time; 
15     dbms_output.put_line(This   statement   end  time : || n_end ); 
16     use_time:=   n_end   -   n_start;  
17     dbms_output.put_line(This   statement   cost   || use_time ||   miliseconds);  
18 end;  
19 --備註:
20 --(1)dbms_utility.get_time 返回當前時間的1/100秒,毫秒
21 --它是用以前後兩個取點做對s比的,單個是沒有具體意義的,就是用來取差值的!
22 
23 --2.執行存儲過程
24 --(21)
25 call thirdPro();
26 --(22)
27 begin  
28    thirdPro();
29 end;  
 1 --案例四:動態sql語句執行
 2 --1.案例
 3 CREATE OR REPLACE PROCEDURE FourthProc(id varchar2 ,dicName VARCHAR2) AS  
 4 mysql VARCHAR2(500);  
 5 BEGIN  
 6   mysql:=UPDATE sys_dictionary SET dic_name=:1 WHERE id=:2;  
 7   EXECUTE IMMEDIATE mysql USING dicName,id; 
 8   commit;
 9 END;
10 
11 --2.執行存儲過程
12 CALL FourthProc(22ff8102-95cd-4862-a2ec-d011eca75ef1,)
 1 --案例五:返回結果集
 2 --1.案例
 3 create or replace procedure FifthPro(
 4        cur_OUT    OUT    SYS_REFCURSOR
 5 ) is
 6 
 7 begin
 8    OPEN cur_OUT FOR
 9       select cname,merch_no,taxno zjid,營業執照 zjname,BUSINESS_LICENSE_VALIDITY validity,trunc(BUSINESS_LICENSE_VALIDITY-sysdate) gqdate from quas.base_merchant
10       where  BUSINESS_LICENSE_VALIDITY-sysdate < 60 ;
11 
12 end FifthPro;

2.案例五:Test測試存儲過程步驟:Test-》點擊Start Debugger 按鈕:開始執行存儲過程-》點擊run按鈕存儲過程直接執行到結束,返回如圖2的結果Cursor->點擊右上角的按鈕,查看結果集:如圖3所示。(若點擊step into 按鈕,則進入存儲過程詳細代碼,按步執行)

技術分享圖片技術分享圖片技術分享圖片

3.java代碼執行存儲過程:

  1 /**
  2  * 
  3  */
  4 package kklazy.reportquery.service;
  5 
  6 import java.sql.CallableStatement;
  7 import java.sql.Connection;
  8 import java.sql.DriverManager;
  9 import java.sql.ResultSet;
 10 import java.sql.SQLException;
 11 import java.util.ArrayList;
 12 import java.util.List;
 13 import javax.transaction.Transactional;
 14 import org.hibernate.Session;
 15 import org.hibernate.internal.SessionFactoryImpl;
 16 import org.springframework.beans.factory.annotation.Value;
 17 import org.springframework.stereotype.Service;
 18 import kklazy.ctps.service.DefaultCtpsService;
 19 import kklazy.reportquery.model.ReportQueryEntity;
 20 import oracle.jdbc.internal.OracleTypes;
 21 
 22 /**
 23  * @author Administrator
 24  * 
 25  */
 26 @Service("fifthProService")
 27 @Transactional(rollbackOn=Exception.class)
 28 public class FifthProService extends DefaultCtpsService<ReportQueryEntity, String>{
 29     //註入jdbc連接參數
 30     @Value("${ctps.database.driver}")
 31     private String driverClass;
 32     @Value("${ctps.database.url}")
 33     private String url;
 34     @Value("${ctps.database.username}")
 35     private String username;
 36     @Value("${ctps.database.password}")
 37     private String password;
 38 
 39     
 40     /**
 41      * 執行存儲過程
 42      */
 43     public List<ReportQueryEntity> execute() {
 44         Session session = (Session) this.getJpa().getManager().getDelegate();
 45         SessionFactoryImpl sessionFactory = (SessionFactoryImpl) session.getSessionFactory();
 46         Connection conn = null;
 47         ResultSet  result = null;
 48         List<ReportQueryEntity> allList = new ArrayList<ReportQueryEntity>();
 49         try {
 50             conn = sessionFactory.getConnectionProvider().getConnection();
 51             if (conn == null || conn.isClosed()) {
 52                 try {
 53                     Class.forName(driverClass);
 54                     conn = DriverManager.getConnection(url, username, password);
 55                 } catch (ClassNotFoundException e) {
 56                     e.printStackTrace();
 57                 }
 58             }
 59         } catch (SQLException e) {
 60             e.printStackTrace();
 61         }
 62         try {
 63             CallableStatement call = conn.prepareCall("{call  FifthPro(?,?)}");
 64             System.out.println();
 65             call.setString(1, "00");
 66             call.registerOutParameter(2, OracleTypes.CURSOR);
 67             call.execute();
 68             result = (ResultSet)call.getObject(2);
 69             if(result == null) {
 70                 System.out.println("查詢失敗!");
 71             }else {
 72                 allList = getFindList(result);
 73                 System.out.println("查詢成功");
 74             }
 75             System.out.println("執行存儲過程的結果是:" + result);
 76         } catch (SQLException e) {
 77             e.printStackTrace();
 78             System.out.println(e);
 79         }finally {
 80             if (conn != null) {
 81                 try {
 82                     conn.close();
 83                 } catch (SQLException e) {
 84                     e.printStackTrace();
 85                 }
 86             }
 87         }
 88         return allList;
 89     }
 90     
 91     public List<ReportQueryEntity> getFindList(ResultSet result) throws SQLException{
 92 
 93         List<ReportQueryEntity> allList = new ArrayList<ReportQueryEntity>();
 94         if(null !=result ) {
 95             while (result.next()) {
 96                 ReportQueryEntity reportEntity = new ReportQueryEntity();
 97                 reportEntity.setData1(result.getString(1));
 98                 reportEntity.setData2(result.getString(2));
 99                 reportEntity.setData3(result.getString(3));
100                 reportEntity.setData4(result.getString(4));
101                 reportEntity.setData5(result.getString(5));
102                 reportEntity.setData6(result.getString(6));
103         
104                 allList.add(reportEntity);
105             }
106         }
107         return allList;
108     }
109     
110 }

案例六、查詢所有數據(遊標的具體使用詳見:https://www.cnblogs.com/xiaoliu66007/p/7495753.html)

PL/SQL 中 SELECT 語句只返回一行數據。如果超過一行數據,那麽就要使用顯式遊標,INTO 子句中要有 SELECT子句中相同列數量的變量。

INTO 子句中也可以是記錄變量。

 1 --案例六:顯式遊標
 2 --------1.用遊標顯示查詢所有的結果  
 3 CREATE OR REPLACE procedure sys_dictionary_proc  
 4 AS  
 5 CURSOR dictionary_emp IS SELECT * FROM sys_dictionary where dic_group =OPERATE_TYPE;--定義遊標,該遊標指向查詢結果  
 6 rowresult sys_dictionary%ROWTYPE;  
 7 BEGIN  
 8   OPEN dictionary_emp;--打開遊標  
 9   LOOP FETCH dictionary_emp INTO rowresult;--將遊標中的值賦給rowresult  
10     EXIT WHEN dictionary_emp%NOTFOUND;--判斷:遊標不存在時跳出循環  
11     dbms_output.put_line(分組:||rowresult.dic_group||值:||rowresult.DIC_VALUE||顯示名:||rowresult.dic_name);  
12   END LOOP;  
13   CLOSE dictionary_emp;--關閉遊標  
14 END;
15 drop procedure sys_dictionary_proc;
16   
17 --2.調用
18 CALL sys_dictionary_proc();  

3.output結果:

分組:OPERATE_TYPE值:1顯示名:新增
分組:OPERATE_TYPE值:2顯示名:修改
分組:OPERATE_TYPE值:3顯示名:刪除

oracle存儲過程相關整理