oracle存儲過程


永不放棄,一切皆有可能!!!

只為成功找方法,不為失敗找借口!

oracle存儲過程

一 、存儲過程說明

1)說明:

     1.存儲過程是用於特定操作的pl/sql語句塊

  2.存儲過程是預編譯過的,經優化后存儲在sql內存中,使用時無需再次編譯,提高了使用效率;

  3.存儲過程的代碼直接存放在數據庫中,一般直接通過存儲過程的名稱調用,減少了網絡流量,加快了系統執行效率;

 

2)存儲過程與函數的區別:

  1.一般來說,存儲過程實現的功能要復雜一點,而函數的實現的功能針對性比較強。

  2.對於存儲過程來說可以返回參數(output),而函數只能返回值或者表對象。

  3.存儲過程一般是作為一個獨立的部分來執行,而函數可以作為查詢語句的一個部分來調用,由於函數可以返回一個表對象,因此它可以在查詢語句中位於FROM關鍵字的后面。

 

3)存儲過程的優點:

  1.執行速度更快 – 在數據庫中保存的存儲過程語句都是編譯過的

  2.允許模塊化程序設計 ,程序的可移植性更強– 類似方法的復用(使用存儲過程可以實現存儲過程設計和編碼工作的分開進行,只要將存儲過程名、參數、返回信息等告訴編程人員即可);

  3.提高系統安全性 – 防止SQL注入 (執行存儲過程的用戶要具有一定的權限才能使用存儲過程)

  4.減少網絡流通量 – 只要傳輸存儲過程的名稱(在大批數據查詢時使用存儲過程分頁查詢比其他方式的分頁要快很多)

  5.在同時進行逐主、從表間的數據維護及有效性驗證時,使用存儲過程更加方便,可以有效的利用SQL中的事務處理機制 

 
二、語法

1)創建存儲過程

復制代碼
CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter1[model] datatype1, parameter2 [model] datatype2..)] IS[AS] BEGIN PL/SQL; END [procedure_name];
復制代碼

說明:

  1. parameter用於指定參數,model用於指定參數模式,datatype用於指定參數類型

  2. 定義存儲過程的參數時,只能指定數據類型,不能指定數據長度

  3. IS/AS用於開始PL/SQL代碼塊

  4. 創建存儲過程時,既可以指定參數也可以不指定任何參數;

  5. 存儲過程參數:1)輸入參數 IN    IN用於接收調用環境的輸入參數(創建存儲過程時,輸入參數的IN可以省略)

           2) 輸出參數 OUT  OUT用於將輸出數據傳遞到調用環境

           3) 輸入輸出參數(IN OUT)其中IN用於接收調用環境的輸入參數,OUT用於將輸出數據傳遞到調用環境

 

2)刪除存儲過程

DROP PROCEDURE procedure_name;

 

3)編譯存儲過程

ALTER PROCEDURE procedure_name COMPILE

 

三、存儲過程調用

1)說明:

  1.在PL/SQL中可以直接引用存儲過程(在SQL*PLUS中調用存儲過程時需要使用call或者execute命令);

  2.當調用存儲過程時,如果無參數,那么直接引用存儲過程名;如果有輸入參數,則需提供輸入參數數值;如果有輸出參數,需要使用變量接收輸出結果;

  3.參數傳遞時有位置傳遞,名稱傳遞和組合傳遞三種方法,三種參數傳遞方式如下:

復制代碼
DECLARE v_para1 varchar2(10); v_para2 nvarchar2(10); v_para3 varchar2(30); v_para4 varchar2(30); BEGIN v_para1 := '123'; v_para2 := '456'; v_para4 := '789'; USP_Learing(v_para1,v_para2,v_para3,v_para4); --位置傳遞    USP_Learing(p_para1=>v_para1,p_para2=>v_para2,p_para3=>v_para3,p_para4=>v_para4); --值傳遞   USP_Learing(v_para1,v_para2,p_para3=>v_para3,p_para4=>v_para4); --組合傳遞 dbms_output.put_line(v_para3); dbms_output.put_line(v_para4); END; 
復制代碼

 

2)存儲過程調用例子

CREATE OR REPLACE PROCUDURE print_Time IS BEGIN DBMS_OUTPUT.PUT_LINE(SYSDATE); END print_time;

  1.pl/sql中直接在pl/sql代碼塊中調用 print_time()即可

  2.sql*plus中  EXEC print_time();

 

四、存儲過程中常用數據類型

1)記錄(RECORD)(單行多列)

2) 表(TABLE)(多行多列)

3) 嵌套表(table)(多行多列)

4)變長數組(VARRY)(多行單列)

5)Common Table Expression (CTE)

 

五、存儲過程中事務處理

1)事務說明:

  1.事務用於確保數據的一致性,有一組相關的DML語句組成,改組DML語句所執行的操作要么全部確認,要么全部取消。

  2.當執行事務操作DML時,oracle會在被作用的表上加鎖,以防止其他用戶改變表結構,同時也會在被作用的行上加鎖,以防止其他事務在該行上執行DML操作

  3.當執行事務提交或者事務回滾時,oracle會確認事務變化或者回滾事務、結束事務、山粗保存點、釋放鎖。

  4. 提交事務(commit)確認事務變化,結束當前事務、刪除保存點,釋放鎖,使得當前事務中所有未決的數據永久改變

  5.保存點(savepoint)在當前事務中,標記事務的保存點

  6. 回滾操作(rollback)回滾整個事務,刪除該事務中所有保存點,釋放鎖,丟棄所有未決的數據改變
  7. ROLLBACK TO SAVEPOINT 回滾到指定的保存點

2)存儲過程中事務說明:

  1.盡可能的讓事務持續的越短越好

  2.在事務中盡可能的存取最少的數據量

3)實例

復制代碼
CREATE OR REPLACE PROCEDURE trancPro IS BEGIN INSERT INTO tab1 VALUES('AA','1212','1313'); COMMIT; SAVEPOINT s1; INSERT INTO tab1 VALUES('BB','1414','1515'); DBMS_TRANSACTION.SAVEPOINT('s2'); UPDATE tab1 SET SNO='1515' WHERE ID='BB'; COMMIT; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK TO SAVEPOINT s1; RAISE_APPLICATION_ERROR(-20010,'ERROR:違反唯一索引約束'); WHEN OTHERS THEN ROLLBACK; END trancPro;
復制代碼

 

六、存儲過程例子

1)簡單例子--利用存儲過程打印日期

CREATE OR REPLACE PROCUDURE print_Time IS BEGIN DBMS_OUTPUT.PUT_LINE(SYSDATE); END print_time;

 

2)例2--包含輸入輸出參數

復制代碼
CREATE OR REPLACE PROCEDURE para_Procedure ( para1        varchar2 :='paraString1', para2        varchar2 default 'paraString2', para3 out   varchar2, para4 in out    varchar2 ) IS BEGIN DECLARE para5 varchar2(20); BEGIN para5 := '輸入輸出參數:'|| para4; para3 := '輸出參數:' || para1 || para2; para4 :=para5; dbms_output.put_line(para5);     dbms_output.put_line('para4 is'||para4); END; END para_Procedure;
復制代碼

 

 

七、java程序調用

在本節中,我們使用java語言調用存儲過程。其中,關鍵是使用CallableStatement這個對象,代碼如下:

復制代碼
String oracleDriverName = "oracle.jdbc.driver.OracleDriver";
 
        // 以下使用的Test就是Oracle里的表空間 String oracleUrlToConnect = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; Connection myConnection = null; try { Class.forName(oracleDriverName); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } try { myConnection = DriverManager.getConnection(oracleUrlToConnect, "xxxx", "xxxx");//此處為數據庫用戶名與密碼  } catch (Exception ex) { ex.printStackTrace(); } try {  CallableStatement proc=null; proc=myConnection.prepareCall("{call xs_proc(?,?)}"); proc.setString(1, "zhangsan"); proc.registerOutParameter(2, Types.NUMERIC); proc.execute(); String teststring=proc.getString(2); System.out.println(teststring); } catch (Exception ex) { ex.printStackTrace(); } 
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM