我正在使用预准备语句jdbc模板运行存储过程:
conn = dbrm.getConnection(this.dataSources.get(aas.getArgumentValue("dataSource")));
Statement stmt = conn.createStatement();
try{
boolean hasResultSet = stmt.execute(query);
catch(Exception e){
// log and handle appropriately
}
我的存储过程基本上是一个调用另外两个存储过程的存储过程。
我遇到的问题是,如果在存储过程的第一个语句之后有异常,那么异常不会返回到jdbc模板,因此看起来我的存储过程对我的java代码起作用了,即使它没有明显的问题。
有没有办法手动检查存储过程的输出或使所有可能的异常冒泡到java?
答案 0 :(得分:2)
似乎在执行存储过程时,引发的异常可能会在成功结果后面“排队”。为了“检索”异常,我们可能必须使用getMoreResults
对象的CallableStatement
方法。
例如,给定存储过程
CREATE PROCEDURE [dbo].[Table1sp] AS
BEGIN
SET NOCOUNT ON;
SELECT 123;
CREATE TABLE #Table1 (textcol VARCHAR(50) PRIMARY KEY);
INSERT INTO #Table1 (textcol) VALUES (NULL); -- error here
END
如果我们运行Java代码
String connectionUrl = "jdbc:sqlserver://localhost:52865;"
+ "databaseName=myDb;" + "integratedSecurity=true";
try (Connection conn = DriverManager.getConnection(connectionUrl)) {
try (CallableStatement cs = conn.prepareCall("{call Table1sp}")) {
cs.execute();
ResultSet rs = cs.getResultSet();
rs.next();
System.out.println(rs.getInt(1));
rs.close();
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
然后我们只打印值123
,我们的代码继续进行,好像没有错。
但是,如果我们跟进getMoreResults()
来电...
String connectionUrl = "jdbc:sqlserver://localhost:52865;"
+ "databaseName=myDb;" + "integratedSecurity=true";
try (Connection conn = DriverManager.getConnection(connectionUrl)) {
try (CallableStatement cs = conn.prepareCall("{call Table1sp}")) {
cs.execute();
ResultSet rs = cs.getResultSet();
rs.next();
System.out.println(rs.getInt(1));
rs.close();
try {
cs.getMoreResults();
} catch (com.microsoft.sqlserver.jdbc.SQLServerException ex) {
System.out.println("SQLServerException: " + ex.getMessage());
}
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
...然后异常被捕获:
123
SQLServerException: Cannot insert the value NULL into column 'textcol', table 'tempdb.dbo.#Table1 ...