![](/img/trans.png)
[英]SQL Server 2012 stored procedure does not return any result in JDBC
[英]JDBC SQL Server Stored Procedure with ResultSet, return value, and output parameters
我正在將應用程序從 Jython 轉換為已編譯的 Java。 該應用程序使用一個主機 SQL 服務器存儲過程來做 CRUD 操作。 所有的過程都定義了一個返回值來指示狀態,並且一些 output 參數用於向應用程序提供反饋。 大多數過程還返回一個結果集。 我正在努力如何檢索返回值和結果集以及 output 參數。
我通常使用 C#,所以 JDBC 的細微差別對我來說是新的。 我一直在測試其中一個插入數據庫的過程,然后在插入的 object 上執行 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
我可以使用以下代碼成功檢索 ResultSet。
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...
}
如果我嘗試使用已注釋掉的行檢索返回值,則會收到一條錯誤消息,指出 ResultSet 已關閉。
com.microsoft.sqlserver.jdbc.SQLServerException:結果集已關閉。
我瀏覽了文檔並了解了如何執行返回值、output 參數和結果集。 但是我怎樣才能利用這三個?
給定存儲過程中的處理順序(插入 select,然后填充結果參數),您需要在使用CallableStatement.getXXX
檢索返回值之前處理結果集。
output 位於從executeQuery()
檢索到的ResultSet rs
中。
您可能希望這樣使用 excute 方法:
call.execute();
String returnValue = call.getString("ResultMessage");
您還希望將 map 正確地轉換為 output 類型。
一旦執行查詢執行,您的連接就會關閉。 基本上 mysql jdbc 連接隱式擴展到 AutoCloseable。 由於您的結果只是過程中的實體,請通過索引 0 獲取值並進行適當的索引超出范圍異常處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.