存儲過程的 概念:
存儲過程:就是一塊PLSQL語句包裝起來,起個名稱
語法上:相當於plsql語句戴個帽子。
相對而言:單純plsql可以認為是匿名程序。
存儲作用:
1, 在開發程序中,為了一個特定的業務功能,會向數據庫進行多次連接關閉(連接和關閉是很耗費資源)。這種就需要對數據庫進行多次I/O讀寫,性能比較低。如果把這些業務放到PLSQL中,在應用程序中只需要調用PLSQL就可以做到連接關閉一次數據庫就可以實現我們的業務,可以大大提高效率.
2, ORACLE官方給的建議:能夠讓數據庫操作的不要放在程序中。在數據庫中實現基本上不會出現錯誤,在程序中操作可以會存在錯誤.(如果在數據庫中操作數據,可以有一定的日志恢復等功能.)
提示:
l plsql是存儲過程的基礎。
l java是不能直接調用plsql的,但可以通過存儲過程這些對象來調用。
存儲過程的語法:
create or replace PROCEDURE 過程名(參數名) AS/IS plsql子程序體
根據參數的類型,我們將其分為3類講解:
l 不帶參數的
l 帶輸入參數的
l 帶輸入輸出參數的。
<1>無參存儲:
創建存儲:建議使用PROCEDURE這個窗口
create or replace procedure p_hello IS
begin
dbms_output.put(
'b'
);
--寫入buffer但不輸出
dbms_output.new_line;
--回車(換行),輸出
dbms_output.put_line(
'hello world!'
);
--輸出並換行
end p_hello
測試存儲:
調用方法:
如何調用執行,兩種方法:
l 一種是是用exec命令來調用—用來測試存儲
exec過程名
l 一種是用其他的程序(plsql和java)來調用
l 程序調用
BEGIN
sayhelloworld;
sayhelloworld;
sayhelloworld;
END;
帶書輸入參數IN
示例
查詢並打印某個員工(如7839號員工)的姓名和薪水--存儲過程:要求,調用的時候傳入員工編號,自動控制台打印:
create or replace procedure p_queryempsal(i_empno IN emp.empno%TYPE)
IS
--聲明變量
v_ename emp.empname%TYPE;
v_sal emp.empsal%TYPE;
select empname,empsal into v_ename,v_sal from emp where empno=i_empno;
dbms_output.put_line('姓名:'||v_ename||',薪水:'||v_sal);
end p_queryempsal;
--命令調用
exec p_queryempsal(7878);
--程序調用
declare
i_empno emp.empno%TYPE:=8989;
BEGIN
p_queryempsal(i_empno );
END;
帶輸入參數IN和輸出結果OUT-----主要是其他程序調用
示例:
----輸入員工號查詢某個員工(7839號(老大)員工)信息,要求,將薪水作為返回值輸出,給調用的程序使用。
CREATE OR REPLACE PROCEDURE p_queryempsal_out( i_empno IN emp.empno%TYPE,o_sal OUT emp.sal%TYPE)
AS
BEGIN
--賦值:將薪水的值賦給輸出的參數o_sal
SELECT sal INTO o_sal FROM emp WHERE empno=i_empno;
END;
調用:
DECLARE
--輸入參數值
v_empno emp.empno%TYPE:=7839;
--聲明一個變量來接收輸出參數
v_sal emp.sal%TYPE;
BEGIN
p_queryempsal_out(v_empno,v_sal);--第二個參數是輸出的參數,必須有變量來接收!!
--當上面的語句執行之后,v_sal就有值了。
dbms_output.put_line('員工編號為:'||v_empno||'的薪資為:'||v_sal);
END;
java程序如何調用存儲過程:
//獲取連接
Connection conn = JDBCUtils.getConnection();
String sql="{call p_queryempsal_out(?,?)}";//轉義sql
CallableStatement call = conn.prepareCall(sql);
//1.輸入參數
call.setInt(1, 7839);//索引位置
call.registerOutParameter(2, OracleTypes.DOUBLE);//第一個參數是占位符,第二個參數數據類型
//執行存儲
call.execute();//執行的時候,會自動將參數傳入數據庫,將輸出參數返回的數據,封裝會call對象中。
//獲取輸出參數的值
double sal = call.getDouble(2);
System.out.println("薪資是:"+sal);
//釋放資源
JDBCUtils.release(conn, call, null);
結果如下: