1.存儲過程
(1)定義過程時,使用 DELIMITER $$ 命令將語句的結束符號從分號 ; 臨時改爲兩個 $$,使得過程體中使用的分號被直接傳遞到服務器,而不會被客戶端(如mysql)解釋。
delimiter $$
create procedure find(in num1 int)
begin
select * from student where stuno = num1;
end$$
delimiter ;
call find(1);
delimiter $$
create procedure add_three_num(in num1 int,in num2 int,in num3 int,out re int)
begin
set re = num1+num2+num3;
end$$
delimiter ;
2.存儲函數
(1)建立存儲函數的時候報錯 “This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) ”,打開my.ini,添加上 log_bin_trust_function_creators=1
delimiter $$
create function add_twonum_function(a int,b int,c int) returns int
begin
return a+b+c;
end$$
delimiter ;
select add_twonum_function(20,30,40);
3.使用CallableStatement調用
package servletDemo;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
public class JDBCCallableStatement {
private static final String URL = "jdbc:MySQL://localhost:3306/hotel?&useSSL=false&serverTimezone=UTC";
private static final String USERNAME = "root";
private static final String PWD = "root";
public static void invokeprocedure(){//增刪改
//調用存儲過程和存儲函數callableStatement
Connection connection = null;//因爲有可能還麼有用到connection就報錯了 那麼這個對象是空的就不能使用close方法
CallableStatement cstmt = null;//同理
try{
//1導入驅動,加載具體的驅動類
Class.forName("com.mysql.cj.jdbc.Driver");
//2與DB建立連接
connection = DriverManager.getConnection(URL, USERNAME, PWD);
//3發送sql語句,執行(增刪改)
//cstmt需要預編譯sql
//num1 + num2 + num3 = result
cstmt = connection.prepareCall( "{ call add_three_num(?,?,?,?) }" ) ;
// cstmt = connection.prepareCall(sql);
cstmt.setInt(1,10);
cstmt.setInt(2,25);
cstmt.setInt(3,10);
cstmt.registerOutParameter(4, Types.INTEGER);
cstmt.execute();
int result = cstmt.getInt(4);
System.out.println(result);
}catch (ClassNotFoundException e) {//Class.forName()的異常
e.printStackTrace();
} catch (SQLException e) {//connection.createStatement()異常
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}finally{//用finally的原因是無論有沒有異常都需要關閉連接
try{
if(cstmt!=null){//執行sql語句
cstmt.close();
}
if(connection!=null){//建立java代碼和數據庫的連接
connection.close();
}
}catch(SQLException e) {//前面兩個close 都會拋SQLException異常
e.printStackTrace();
}
}
}
public static void invokeFunction(){//增刪改
//調用存儲過程和存儲函數callableStatement
Connection connection = null;//因爲有可能還麼有用到connection就報錯了 那麼這個對象是空的就不能使用close方法
CallableStatement cstmt = null;//同理
try{
//1導入驅動,加載具體的驅動類
Class.forName("com.mysql.cj.jdbc.Driver");
//2與DB建立連接
connection = DriverManager.getConnection(URL, USERNAME, PWD);
//3發送sql語句,執行(增刪改)
//cstmt需要預編譯sql
//num1 + num2 = result
String sql = "{? = call add_twonum_function(?,?,?)}";
cstmt = connection.prepareCall(sql) ;
// cstmt = connection.prepareCall(sql);
cstmt.registerOutParameter(1, Types.INTEGER);
cstmt.setInt(2,10);
cstmt.setInt(3,10);
cstmt.setInt(4,10);
// cstmt.registerOutParameter(4, Types.INTEGER);
cstmt.execute();
int result = cstmt.getInt(1);
System.out.println(result);
}catch (ClassNotFoundException e) {//Class.forName()的異常
e.printStackTrace();
} catch (SQLException e) {//connection.createStatement()異常
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}finally{//用finally的原因是無論有沒有異常都需要關閉連接
try{
if(cstmt!=null){//執行sql語句
cstmt.close();
}
if(connection!=null){//建立java代碼和數據庫的連接
connection.close();
}
}catch(SQLException e) {//前面兩個close 都會拋SQLException異常
e.printStackTrace();
}
}
}
public static void main(String [] args){
invokeprocedure();
invokeFunction();
}
}