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();
}
}