1 存儲過程和函數
指存儲在數據庫中供所有用戶程序調用的子程序叫存儲過程和存儲函數
1.1 創建存儲過程語法
Create [or replace] procedure 過程名(參數)
as
PLSQL子程序
無參數的存儲過程
set SERVEROUTPUT ON;
--創建一個存儲過程
create or replace procedure sayHelloWord
as
--說明部份
begin
DBMS_OUTPUT.PUT_LINE('Hello Word');
end;
調用存儲過程 第一方式
EXECUTE sayHelloWord();
調用存儲過程 第二方式
begin
sayHelloWord();
sayHelloWord();
end;
帶參數的存儲過程
--給指定的員工漲工資100,並且漲前漲後的薪水
create or replace procedure raisesalary(eno in number)
as
psal emp.sal%type;
begin
--得到當前薪水
select sal into psal from emp where empno = eno;
--漲100
update emp set sal=sal+100 where empno=eno;
--打印
DBMS_OUTPUT.put_line('漲前:'||psal||' 漲後:'||(psal + 100));
end;
--調用存儲過程
set serveroutput on
begin
raisesalary(7369);
raisesalary(7369);
--需要在這裏提交事務,不要在內部提交
commit;
end;
1.2 存儲過程調試
- 如圖,存儲過程可調試,但在調試前需要給於權限
- 然後加斷點調試,先選擇調用,用法跟java的調試差不多
1.3 存儲函數
函數(Function)爲一命名的存儲函數,可以帶參數,並返回一計算值。函數和過程的結構相似,但必需要有一個return語句,用於返回函數值。函數說明要指定函數名、結果值的類型,以及參數類型。
函數聲明 【計算年薪】
create or replace function queryincome(eno in number) return number
as
psal emp.sal%type;--月薪
pcomm emp.comm%type;--獎金
begin
--得到當前月薪和獎金
select sal,comm into psal,pcomm from emp where empno = eno;
--返回年收入
return psal*12 + nvl(pcomm,0);
end;
函數調用
set serveroutput on
--函數的調用
declare
y_sal number;
begin
y_sal:=queryincome(7369);
DBMS_OUTPUT.put_line('年薪:'||y_sal);
end;
什麼時候用存儲函數和存儲過程
如果有一個返回值就用存儲函數,否則就用存儲過程
2 java中調用存儲過程和函數
創建一個存儲過程【根據員工編號返回員工名字和工資】
create or replace procedure queryempinfo(eno in number,empname out varchar,empsal out number)
as
psal emp.sal%type;
begin
select ename,sal into empname,empsal from emp where empno = eno;
end;
2.1 IDEA maven 創建普通 java項目
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.oracle.ojdbc/ojdbc8 -->
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
</dependency>
</dependencies>
- 工具類
package com.tzb.oracletest;
import java.sql.*;
public class JDBCUtils {
private static String driver = "oracle.jdbc.OracleDriver";
private static String url = "jdbc:oracle:thin:@192.168.10.10:1521:orcl";
private static String user = "scott";
private static String password = "Orcl1234";
static{
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
// TODO: handle exception
e.printStackTrace();
}
}
/**
* 返回一個數據連接
* */
public static Connection getConnection(){
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void release(Connection conn, Statement st, ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
rs = null;//釋放
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
st = null;//釋放
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
conn = null;//釋放
}
}
}
}
2.2 調用存儲過程
package com.tzb.oracletest;
import oracle.jdbc.OracleType;
import oracle.jdbc.OracleTypes;
import org.junit.Test;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
/**
* Unit test for simple App.
*/
public class AppTest {
@Test
public void test() {
Connection conn = null;
CallableStatement call = null;
try {
conn = JDBCUtils.getConnection();
// create or replace procedure queryempinfo(eno in number,empname out varchar,empsal out number)
//存儲過程的java寫法{call <procedure-name>[(<arg1>,<arg2>, ...)]}
String sql = "{call queryempinfo(?,?,?)}";
call = conn.prepareCall(sql);
// 設置存儲過程參數
call.setInt(1,7369);
// 設置返回值類型
call.registerOutParameter(2, OracleTypes.VARCHAR);
call.registerOutParameter(3, OracleTypes.NUMBER);
// 調用
call.execute();
// 獲取返回值
System.out.println("員工名字:" + call.getString(2));
System.out.println("工資:" + call.getDouble(3));
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.release(conn,call,null);
}
}
}
2.3 調用存儲函數
create or replace function queryincome(eno in number) return number
as
psal emp.sal%type;--月薪
pcomm emp.comm%type;--獎金
begin
--得到當前月薪和獎金
select sal,comm into psal,pcomm from emp where empno = eno;
--返回年收入
return psal*12 + nvl(pcomm,0);
end;
@Test
public void test2() {
Connection conn = null;
CallableStatement call = null;
try {
conn = JDBCUtils.getConnection();
//create or replace function queryincome(eno in number) return number
//{?=call <funtion-name>[(<arg1>,<arg2>, ...)]}
String sql = "{?=call queryincome(?) }";
call = conn.prepareCall(sql);
// 設置存儲過程參數
call.setInt(2,7369);
// 設置返回值類型
call.registerOutParameter(1, OracleTypes.NUMBER);
// 調用
call.execute();
// 獲取返回值;
System.out.println("年收入:" + call.getDouble(1));
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.release(conn,call,null);
}
}