JDBC SQL 带结果集的服务器存储过程、return 值和输出参数
JDBC SQL Server Stored Procedure with ResultSet, return value, and output parameters
我正在将应用程序从 Jython 转换为编译 Java。该应用程序使用大量 SQL 服务器存储过程来执行 CRUD 操作。所有过程都使用指示状态的 return 值和一些用于向应用程序提供反馈的输出参数定义。大多数程序还return一个结果集。我正在为如何检索 return 值以及结果集和输出参数而苦苦挣扎。
我通常使用 C#,所以 JDBC 的细微差别对我来说是新的。我一直在测试其中一个程序,该程序执行对数据库的插入,然后对插入的对象执行 select。
这是一个简化的示例过程仅用于说明目的。实际过程比这复杂。
CREATE PROCEDURE [dbo].[sp_Thing_Add]
(
@Name NVARCHAR(50),
@Description NVARCHAR(100),
@ResultMessage NVARCHAR(200) = N'' OUTPUT
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @Result INT = -1
DECLARE @ResultMessage = 'Procedure incomplete'
BEGIN TRY
INSERT INTO Things (Name, Description) VALUES (@Name, @Description)
SELECT * FROM Things WHERE ThingID = SCOPE_IDENTITY()
END TRY
BEGIN CATCH
SELECT @Result = CASE WHEN ERROR_NUMBER() <> 0 THEN ERROR_NUMBER() ELSE 1 END,
@ResultMessage = ERROR_MESSAGE()
GOTO EXIT_SUB
END CATCH
SUCCESS:
SET @Result = 0
SET @ResultMessage = N'Procedure completed successfully'
RETURN @Result
EXIT_SUB:
IF @Result <> 0
BEGIN
-- Do some error handling stuff
END
RETURN @Result
我可以使用以下代码成功检索结果集。
var conn = myConnectionProvider.getConnection();
String sql = "{? = call dbo.sp_Thing_Add(?, ?, ?)}"
call = conn.prepareCall(sql);
call.registerOutParameter(1, TYPES.Integer); // Return value
call.setString("Name", thing.getName());
call.setString("Description", thing.getDescription());
call.registerOutParameter("ResultMessage", TYPES.NVARCHAR);
ResultSet rs = call.executeQuery();
// Try to get the return value. This appears to close the ResultSet and prevents data retrieval.
//int returnValue = call.getInt(1);
// Normally there'd be a check here to make sure things executed properly,
// and if necessary the output parameter(s) may also be leveraged
if (rs.next()) {
thing.setId(rs.getLong("ThingID"));
// Other stuff actually happens here too...
}
如果我尝试使用注释掉的行检索 return 值,我会收到一条错误消息,指出 ResultSet 已关闭。
com.microsoft.sqlserver.jdbc.SQLServerException: The result set is closed.
我已阅读文档并了解了如何处理 return 值、输出参数和结果集。但是我怎样才能利用所有 3 个?
输出在从 executeQuery()
检索到的 ResultSet rs
中。
您可能想这样使用执行方法:
call.execute();
String returnValue = call.getString("ResultMessage");
您还想正确映射到输出类型。
执行查询后,您的连接已关闭。基本上 mysql jdbc 连接隐式扩展到 AutoCloseable。由于您的结果只是来自过程的实体,请通过索引 0 获取值并进行适当的索引超出绑定异常处理。
给定存储过程中的处理顺序(插入,select,然后填充结果参数),您需要在检索结果集之前处理结果集 return 值 CallableStatement.getXXX
.
我正在将应用程序从 Jython 转换为编译 Java。该应用程序使用大量 SQL 服务器存储过程来执行 CRUD 操作。所有过程都使用指示状态的 return 值和一些用于向应用程序提供反馈的输出参数定义。大多数程序还return一个结果集。我正在为如何检索 return 值以及结果集和输出参数而苦苦挣扎。
我通常使用 C#,所以 JDBC 的细微差别对我来说是新的。我一直在测试其中一个程序,该程序执行对数据库的插入,然后对插入的对象执行 select。
这是一个简化的示例过程仅用于说明目的。实际过程比这复杂。
CREATE PROCEDURE [dbo].[sp_Thing_Add]
(
@Name NVARCHAR(50),
@Description NVARCHAR(100),
@ResultMessage NVARCHAR(200) = N'' OUTPUT
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @Result INT = -1
DECLARE @ResultMessage = 'Procedure incomplete'
BEGIN TRY
INSERT INTO Things (Name, Description) VALUES (@Name, @Description)
SELECT * FROM Things WHERE ThingID = SCOPE_IDENTITY()
END TRY
BEGIN CATCH
SELECT @Result = CASE WHEN ERROR_NUMBER() <> 0 THEN ERROR_NUMBER() ELSE 1 END,
@ResultMessage = ERROR_MESSAGE()
GOTO EXIT_SUB
END CATCH
SUCCESS:
SET @Result = 0
SET @ResultMessage = N'Procedure completed successfully'
RETURN @Result
EXIT_SUB:
IF @Result <> 0
BEGIN
-- Do some error handling stuff
END
RETURN @Result
我可以使用以下代码成功检索结果集。
var conn = myConnectionProvider.getConnection();
String sql = "{? = call dbo.sp_Thing_Add(?, ?, ?)}"
call = conn.prepareCall(sql);
call.registerOutParameter(1, TYPES.Integer); // Return value
call.setString("Name", thing.getName());
call.setString("Description", thing.getDescription());
call.registerOutParameter("ResultMessage", TYPES.NVARCHAR);
ResultSet rs = call.executeQuery();
// Try to get the return value. This appears to close the ResultSet and prevents data retrieval.
//int returnValue = call.getInt(1);
// Normally there'd be a check here to make sure things executed properly,
// and if necessary the output parameter(s) may also be leveraged
if (rs.next()) {
thing.setId(rs.getLong("ThingID"));
// Other stuff actually happens here too...
}
如果我尝试使用注释掉的行检索 return 值,我会收到一条错误消息,指出 ResultSet 已关闭。
com.microsoft.sqlserver.jdbc.SQLServerException: The result set is closed.
我已阅读文档并了解了如何处理 return 值、输出参数和结果集。但是我怎样才能利用所有 3 个?
输出在从 executeQuery()
检索到的 ResultSet rs
中。
您可能想这样使用执行方法:
call.execute();
String returnValue = call.getString("ResultMessage");
您还想正确映射到输出类型。
执行查询后,您的连接已关闭。基本上 mysql jdbc 连接隐式扩展到 AutoCloseable。由于您的结果只是来自过程的实体,请通过索引 0 获取值并进行适当的索引超出绑定异常处理。
给定存储过程中的处理顺序(插入,select,然后填充结果参数),您需要在检索结果集之前处理结果集 return 值 CallableStatement.getXXX
.