Java中JDBC调用存储过程和函数的核心是CallableStatement:调用无返回值过程用{call proc_name(?,?)};带OUT参数需registerOutParameter()注册后getXXX()获取;函数调用用{? = call func_name(?)}并注册返回值;返回ResultSet时用execute()和getResultSet()处理。

Java 中通过 JDBC 调用存储过程和函数,核心是使用 CallableStatement —— 它是 PreparedStatement 的子接口,专为执行数据库存储过程(Stored Procedure)和函数(Function)设计。
调用存储过程(无返回值)
适用于执行 INSERT/UPDATE/DELETE 等操作,或仅做业务逻辑处理、不返回结果的存储过程。
关键步骤:
- SQL 字符串用
{call proc_name(?, ?)}格式,参数用?占位 - 通过
Connection.prepareCall()创建CallableStatement - 用
setXxx(index, value)设置输入参数(索引从 1 开始) - 调用
execute()执行
示例(MySQL,调用无返回过程 update_salary(emp_id, amount)):
立即学习“Java免费学习笔记(深入)”;
String sql = "{call update_salary(?, ?)}";
try (CallableStatement cs = conn.prepareCall(sql)) {
cs.setInt(1, 1001);
cs.setDouble(2, 500.0);
cs.execute();
}
调用带输出参数的存储过程
当过程需要返回值(如状态码、计算结果、OUT 参数),需显式注册输出参数类型,并在执行后用 getXXX() 获取。
注意点:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
registerOutParameter(index, Types.XXX)声明输出参数类型(如Types.INTEGER、Types.VARCHAR) - 输入参数仍用
setXxx(),输出参数不设值 - 必须在
execute()后调用getXXX(index)获取结果
示例(Oracle 或 PostgreSQL 兼容写法,过程 get_emp_info(id, name_out, salary_out)):
String sql = "{call get_emp_info(?, ?, ?)}";
try (CallableStatement cs = conn.prepareCall(sql)) {
cs.setInt(1, 1001);
cs.registerOutParameter(2, Types.VARCHAR);
cs.registerOutParameter(3, Types.DOUBLE);
cs.execute();
String name = cs.getString(2);
double salary = cs.getDouble(3);
System.out.println(name + ": " + salary);
}
调用数据库函数(有返回值)
函数必须返回一个值,JDBC 中用 {? = call func_name(?)} 语法,第一个 ? 表示返回值占位符。
操作要点:
- 返回值参数也需用
registerOutParameter(1, type)注册(索引固定为 1) - 其余参数按顺序设置输入值
- 执行后用
getXxx(1)获取函数返回结果
示例(调用函数 calculate_bonus(salary) 返回 DOUBLE):
String sql = "{? = call calculate_bonus(?)}";
try (CallableStatement cs = conn.prepareCall(sql)) {
cs.registerOutParameter(1, Types.DOUBLE);
cs.setDouble(2, 8500.0);
cs.execute();
double bonus = cs.getDouble(1);
System.out.println("Bonus: " + bonus);
}
处理结果集(存储过程返回 ResultSet)
某些存储过程会用 SELECT 返回结果集(如 SQL Server、MySQL 5.7+、PostgreSQL)。此时不能用 getXXX(),而要像 Statement 一样用 execute() + getResultSet()。
关键细节:
- 调用
execute()(不是executeQuery()),它返回布尔值:true 表示首个结果是 ResultSet - 用
getResultSet()获取结果集,再用标准ResultSet方式遍历 - 若过程含多个结果集或更新计数,可用
getMoreResults()切换
示例(MySQL 过程 list_active_users() 返回用户列表):
String sql = "{call list_active_users()}";
try (CallableStatement cs = conn.prepareCall(sql)) {
boolean hasRS = cs.execute();
if (hasRS) {
try (ResultSet rs = cs.getResultSet()) {
while (rs.next()) {
System.out.println(rs.getString("name") + ", " + rs.getInt("age"));
}
}
}
}

















