在PL/SQL中呼叫儲存過程--oracle
阿新 • • 發佈:2018-12-30
在oracle10中寫好了儲存過程,程式碼如下: CREATE OR REPLACE Procedure Proc_Insert ( sName in varchar2, sAge in int, sExeTime in varchar2 ) is begin Insert into T_TEST(C_ID, C_NAME, C_AGE, C_INTIME, C_EXETIME) values(T_TEST_CID.nextval,sName,sAge, sysdate, to_date(sExeTime, 'yyyy-mm-dd')); end Proc_Insert; 為了在PL/SQL中呼叫這個儲存過程,採用瞭如下的程式碼: begin Proc_Insert('hello6',25,'2005-12-24'); commit; end; 另外增加了一個儲存過程,但是sExeTime是date型別,那麼呼叫的時候,就必須先把字串轉換成date型別,否則將會呼叫失敗。 儲存過程: CREATE OR REPLACE Procedure Proc_Insert2 ( sName in varchar2, sAge in int, sExeTime in date ) is begin Insert into T_TEST(C_ID, C_NAME, C_AGE, C_INTIME, C_EXETIME) values(T_TEST_CID.nextval,sName,sAge, sysdate, sExeTime); end Proc_Insert2; 呼叫的程式碼: begin Proc_Insert2('hellowhat', 26, to_date('2010-10-20', 'yyyy-mm-dd')); commit; end;
呼叫儲存過程 儲存過程建立完成後,只要通過授權,使用者就可以在SQLPLUS 、ORACLE開發工具或第三方開發工具中來呼叫執行。ORACLE 使用EXECUTE 語句來實現對儲存過程的呼叫: EXEC[UTE] Procedure_name( parameter1, parameter2…); 例:查詢指定員工記錄; CREATE OR REPLACE PROCEDURE QueryEmp (v_empno IN emp.empno%TYPE, v_ename OUT emp.ename%TYPE, v_sal OUT emp.sal%TYPE) AS BEGIN SELECT ename, sal INTO v_ename, v_sal FROM emp WHERE empno=v_empno; DBMS_OUTPUT.PUT_LINE('編碼為'||v_empno||'的員工已經查到!'); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('你需要的資料不存在!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('發生其它錯誤!'); END QueryEmp; 呼叫方法: DECLARE v1 emp.ename%TYPE; v2 emp.sal%TYPE; BEGIN QueryEmp(7788, v1, v2); DBMS_OUTPUT.PUT_LINE('姓名:'||v1); DBMS_OUTPUT.PUT_LINE('工資:'||v2); QueryEmp(7902, v1, v2); DBMS_OUTPUT.PUT_LINE('姓名:'||v1); DBMS_OUTPUT.PUT_LINE('工資:'||v2); QueryEmp(8899, v1, v2); DBMS_OUTPUT.PUT_LINE('姓名:'||v1); DBMS_OUTPUT.PUT_LINE('工資:'||v2); END; 例.計算指定部門的工資總和,並統計其中的職工數量。 CREATE OR REPLACE PROCEDURE proc_demo (Dept_no NUMBER DEFAULT 10, Sal_sum OUT NUMBER, Emp_count OUT NUMBER) IS BEGIN SELECT SUM(sal), COUNT(*) INTO sal_sum, emp_count FROM emp WHERE deptno=dept_no; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('你需要的資料不存在!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('發生其它錯誤!'); END proc_demo; 呼叫方法: DECLARE V_num NUMBER; V_sum NUMBER(8, 2); BEGIN Proc_demo(30, v_sum, v_num); DBMS_OUTPUT.PUT_LINE('30號部門工資總和:'||v_sum||’,人數:’||v_num); Proc_demo(sal_sum => v_sum, emp_count => v_num); DBMS_OUTPUT.PUT_LINE('10號部門工資總和:'||v_sum||’,人數:’||v_num); END; 在PL/SQL 程式中還可以在塊內建立本地函式和過程,這些函式和過程不儲存在資料庫中,但可以在建立它們的PL/SQL 程式中被重複呼叫。本地函式和過程在PL/SQL 塊的宣告部分定義,它們的語法格式與儲存函式和過程相同,但不能使用CREATE OR REPLACE 關鍵字。 例:建立本地過程,用於計算指定部門的工資總和,並統計其中的職工數量; DECLARE V_num NUMBER; V_sum NUMBER(8, 2); PROCEDURE proc_demo (Dept_no NUMBER DEFAULT 10, Sal_sum OUT NUMBER, Emp_count OUT NUMBER) IS BEGIN SELECT SUM(sal), COUNT(*) INTO sal_sum, emp_count FROM emp WHERE deptno=dept_no; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('你需要的資料不存在!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('發生其它錯誤!'); END proc_demo; BEGIN Proc_demo(30, v_sum, v_num); DBMS_OUTPUT.PUT_LINE('30號部門工資總和:'||v_sum||’,人數:’||v_num); Proc_demo(sal_sum => v_sum, emp_count => v_num); DBMS_OUTPUT.PUT_LINE('10號部門工資總和:'||v_sum||’,人數:’||v_num); END;
儲存過程 1 什麼是儲存過程? 用於在資料庫中完成特定的操作或者任務。是一個PLSQL程式塊,可以永久的儲存在資料庫中以供其他程式呼叫。 2 儲存過程的引數模式 儲存過程的引數特性: IN型別的引數 OUT型別的引數 IN-OUT型別的引數 值被 傳遞給子程式 返回給呼叫環境 傳遞給子程式 返回給呼叫環境 引數形式 常量 未初始化的變數 初始化的變數 使用時 預設型別 必須明確指定 必須明確指定 3 無引數儲存過程的使用: CREATE OR REPLACE PROCEDURE 過程名 [(parameter,...)] IS 定義變數 Begin Plsql程式 End; 例:建立一個儲存過程,用於向資料庫中插入一條記錄。 第一步:建立 CREATE OR REPLACE PROCEDURE pro_1 IS Begin insert into person values (11,'aa','aav'); End; 第二步:在sql*plus中執行該過程 exec pro_1; 第三步:通過JDBC使用儲存過程。 private Connection conn = null; private ResultSet rs = null; private CallableStatement state = null; //呼叫一個無引數的儲存過程 public void testPro() { conn = Tools.getConnection(); try { state = conn.prepareCall("{call pro_1}"); state.execute(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } 4 帶有IN型別引數的儲存過程的使用。 例:建立一個儲存過程,用於向資料庫中插入一條記錄。 第一步:建立 CREATE OR REPLACE PROCEDURE pro_2(id number,name varchar2,email varchar2) IS Begin insert into person values (id,name,email); End; 第二步:在sql*plus中執行該過程 exec pro_2(12,'aaa','aaa'); 第三步:通過JDBC使用儲存過程。 //使用一個帶有 IN 型別引數的儲存過程 public void testPro_in(int id,String name,String email) { conn = Tools.getConnection(); try { state = conn.prepareCall("{call pro_2(?,?,?)}"); state.setLong(1, id); state.setString(2, name); state.setString(3, email); state.execute(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } 5 帶有out型別引數的儲存過程的使用。 例:建立一個儲存過程,用於返回資料庫中的Person表的總行數。 第一步:建立 CREATE OR REPLACE PROCEDURE pro_3(num out number) IS mynum number; Begin select count(*) into mynum from person; num := mynum; End; 或者 CREATE OR REPLACE PROCEDURE pro_3(num out number) IS Begin select count(*) into num from person; End; 第二步:在sql*plus中執行該過程 declare a number; begin pro_3(a); dbms_output.put_line(a); end; 第三步:通過JDBC使用儲存過程。 public void testPro_out() { conn = Tools.getConnection(); try { state = conn.prepareCall("{call pro_3(?)}"); state.registerOutParameter(1, Types.NUMERIC); state.execute(); int num = state.getInt(1); System.out.println(num); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } 6 帶有in-out型別引數的儲存過程的使用。 建立: CREATE OR REPLACE PROCEDURE pro_4(num in out number) IS a number := 100; Begin num := a*num; End; 在sql*plus中執行該過程 declare a number := 12; begin pro_4(a); dbms_output.put_line(a); end; 練習: 已知有一員工表,請編寫一個儲存過程,可以通過部門ID得到該部門員工的平