Java 调用 SQL Server 存储过程
在 Java 中调用 SQL Server 存储过程有几种方法,我将介绍最常用的两种方式:使用 JDBC 和使用 Spring 的 JdbcTemplate。

使用 JDBC 直接调用
基本步骤
- 加载 JDBC 驱动
- 建立数据库连接
- 创建 CallableStatement 对象
- 设置参数
- 执行存储过程
- 处理结果
- 关闭资源
示例代码
import java.sql.*;
import java.util.Scanner;
public class CallStoredProcedureExample {
// 数据库连接信息
private static final String DB_URL = "jdbc:sqlserver://localhost:1433;databaseName=YourDatabase";
private static final String USER = "username";
private static final String PASS = "password";
public static void main(String[] args) {
Connection conn = null;
CallableStatement cstmt = null;
try {
// 1. 加载 JDBC 驱动
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
// 2. 建立数据库连接
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 3. 创建 CallableStatement 对象
// 假设存储过程名为 usp_GetEmployeeById,有一个输入参数 @id 和一个输出参数 @name
String sql = "{call usp_GetEmployeeById(?, ?)}";
cstmt = conn.prepareCall(sql);
// 4. 设置参数
Scanner scanner = new Scanner(System.in);
System.out.print("请输入员工ID: ");
int empId = scanner.nextInt();
// 设置输入参数
cstmt.setInt(1, empId);
// 注册输出参数
cstmt.registerOutParameter(2, Types.VARCHAR);
// 5. 执行存储过程
cstmt.execute();
// 6. 获取输出参数
String empName = cstmt.getString(2);
System.out.println("员工姓名: " + empName);
} catch (SQLException se) {
// 处理 JDBC 错误
se.printStackTrace();
} catch (Exception e) {
// 处理 Class.forName 错误
e.printStackTrace();
} finally {
// 7. 关闭资源
try {
if (cstmt != null) cstmt.close();
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
}
}
处理返回结果集
如果存储过程返回结果集,可以使用以下方式处理:
// 假设存储过程返回一个结果集
ResultSet rs = null;
try {
// 执行存储过程
boolean hasResults = cstmt.execute();
if (hasResults) {
rs = cstmt.getResultSet();
while (rs.next()) {
// 处理结果集
System.out.println("ID: " + rs.getInt("id") +
", Name: " + rs.getString("name"));
}
}
// 处理输出参数
String outputParam = cstmt.getString(3); // 假设第三个参数是输出参数
System.out.println("输出参数: " + outputParam);
} finally {
if (rs != null) rs.close();
}
使用 Spring JdbcTemplate
如果你正在使用 Spring 框架,可以使用 JdbcTemplate 来简化调用。
添加依赖
确保你的项目中包含 Spring JDBC 和 SQL Server JDBC 驱动:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.4.0.jre11</version>
</dependency>
配置数据源
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
dataSource.setUrl("jdbc:sqlserver://localhost:1433;databaseName=YourDatabase");
dataSource.setUsername("username");
dataSource.setPassword("password");
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
调用存储过程
@Service
public class EmployeeService {
@Autowired
private JdbcTemplate jdbcTemplate;
public String getEmployeeNameById(int id) {
// 使用 SimpleJdbcCall 调用存储过程
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("dbo") // 可选
.withProcedureName("usp_GetEmployeeById")
.declareParameters(
new SqlParameter("id", Types.INTEGER),
new SqlOutParameter("name", Types.VARCHAR)
);
// 执行存储过程
Map<String, Object> result = jdbcCall.execute(id);
// 获取输出参数
return (String) result.get("name");
}
// 或者使用更简单的方式(如果只需要输出参数)
public String getEmployeeNameByIdSimple(int id) {
return jdbcTemplate.queryForObject(
"{call usp_GetEmployeeById(?, ?)}",
new Object[]{id},
new int[]{Types.INTEGER, Types.VARCHAR},
String.class,
1 // 指定返回第二个参数
);
}
}
注意事项
- 驱动版本:确保使用与你的 SQL Server 版本兼容的 JDBC 驱动
- 参数类型:正确设置输入参数和输出参数的类型
- 资源管理:始终关闭 Connection、Statement 和 ResultSet
- 异常处理:妥善处理可能出现的 SQL 异常
- 存储过程语法:SQL Server 存储过程的调用语法是
{call procedure_name(?, ?)}
常见问题
"The column name 'xxx' is not valid" 错误
这通常是因为结果集列名与 Java 对象属性名不匹配,确保列名大小写一致或使用别名。

"String or binary data would be truncated" 错误
检查输出参数的长度是否足够大,或者调整存储过程中的数据类型。
驱动加载失败
确保 JDBC 驱动 JAR 文件在类路径中,或者使用 Maven/Gradle 正确管理依赖。
希望这些信息能帮助你成功在 Java 中调用 SQL Server 存储过程!

