在Java中调用存储过程并不常见,所以我担心在线有关该过程的信息有点受限。通常我在开头使用connection.setAutoCommit(false);
,最后使用常规DB-Updates使用connection.commit();
。
在我没有使用c.commit();
行之前,由于这个函数是通过Ajax调用的,我在FireBug中看到Ajax-Request永远不会完成,这使我添加了ps.setQueryTimeout(99);
行。
现在我调用存储过程的方法如下所示:
private void callProcedure(int customer, int user, String stmt) {
Connection c = null;
PreparedStatement ps = null;
try {
c = ConnectionTools.getConnection();
c.setAutoCommit(false);
//"EXEC CustomerUpdate ?, ?";
ps = c.prepareStatement(stmt);
ps.setEscapeProcessing(true);
ps.setQueryTimeout(99);
ps.setInt(1, customer);
ps.setInt(2, user);
ps.executeUpdate();
c.commit();
} catch (NamingException | SQLException ex) {
if (c != null) {
try {
c.rollback();
} catch (SQLException ex1) {
Logger.getLogger(CustomerProcedures.class.getName()).log(Level.SEVERE, null, ex1);
}
}
Logger.getLogger(CustomerProcedures.class.getName()).log(Level.INFO, "SQL: {0}; {1}; {2}", new Object[]{stmt, customer, user});
Logger.getLogger(CustomerProcedures.class.getName()).log(Level.SEVERE, null, ex);
} finally {
ConnectionTools.disconnect(ps, c);
}
}
从与我的问题相关的材料中有一个例子,但是回滚,而不是提交:calling PLSQL procedure from Java - 这个例子看起来很好,因为只有一个与问题本身无关的小错误。在我的印象中,设置conn.setAutoCommit(false);
似乎很好。
在另一个很少引起注意的例子中,没有使用过类似的内容:Java: Calling a stored procedure in an oracle database
在其他来源中我也找不到多少。 Coderanch进行了简短的讨论,但在我的存储过程中没有提交(http://www.coderanch.com/t/621006/java/java/commit-written-procedures-called-Java)
在官方文档中,提交问题也没有太多关注:https://docs.oracle.com/javase/tutorial/jdbc/basics/storedprocedures.html
他们建议您使用prepareCall
代替prepareStatement
和execute
代替executeUpdate
cs = this.con.prepareCall("{call RAISE_PRICE(?,?,?)}");
cs.setString(1, coffeeNameArg);
cs.setFloat(2, maximumPercentageArg);
cs.registerOutParameter(3, Types.NUMERIC);
cs.setFloat(3, newPriceArg);
cs.execute();
只有:
注意:与Statement对象一样,要调用存储过程,您可以 调用execute,executeQuery或executeUpdate取决于多少 过程返回的ResultSet对象。但是,如果你不确定 过程返回多少个ResultSet对象,调用execute。
但到目前为止没有任何承诺...