尝试使用使用Apache DBCP连接池检索的连接对象更新clob列。
早些时候,我使用this实现了连接池,它工作正常,但能够更新CLOB。我切换到DBCP因为我得到 java.sql.SQLException:ORA-01000:超出最大打开游标。我在所有DAO中检查了connection,resultSet,preparedStatement对象。所有 finally 块都关闭了这些游标。仍然面临这个错误,因此决定切换到DBCP。
但是,当我尝试使用此DBCP连接更新CLOB时,应用程序只挂起在 pstmt.executeUpdate()。
Connection conn = null;
PreparedStatement pstmt = null;
CLOB clob = null;
String q = "UPDATE REPORT_TABLE SET RPT_FILE = ? WHERE RPT_SEQ_NUM = ?";
...
conn = DBConnection.getConnection();
pstmt = conn.prepareStatement(q);
clob = getCLOB(xmlReport, conn);
pstmt.setObject(1, clob);
pstmt.setString(2, reportSeqNo);
if (pstmt.executeUpdate() == 1) {
logger.logError("Report has been successfully UPDATED");
}
...
其中getCLOB()方法是:
private CLOB getCLOB(String xmlData, Connection conn) throws SQLException{
CLOB tempClob = null;
try{
// If the temporary CLOB has not yet been created, create new
tempClob = CLOB.createTemporary(conn, true, CLOB.DURATION_SESSION);
// Open the temporary CLOB in readwrite mode to enable writing
tempClob.open(CLOB.MODE_READWRITE);
// Get the output stream to write
Writer tempClobWriter = tempClob.getCharacterOutputStream();
// Write the data into the temporary CLOB
tempClobWriter.write(xmlData);
// Flush and close the stream
tempClobWriter.flush();
tempClobWriter.close();
// Close the temporary CLOB
tempClob.close();
} catch(SQLException sqlexp){
tempClob.freeTemporary();
sqlexp.printStackTrace();
} catch(Exception exp){
exp.printStackTrace();
tempClob.freeTemporary();
exp.printStackTrace();
}
return tempClob;
}
我也试过传递((DelegatingConnection) conn).getInnermostDelegate()
连接,但没有用。
另外,我尝试了Shiny建议here的内容。这次它在我选择数据时挂起。
使用Oracle 9i和JDBC Oracle驱动程序版本大于10(抱歉,现在还记不清确切版本)。
答案 0 :(得分:1)
您是否尝试过使用PreparedStatement.setClob
方法代替setObject
?
答案 1 :(得分:1)
使用Oracle JDBC驱动程序,您无法使用setClob()
。它不会抛出错误,但它也不起作用。这背后的原因是JDBC驱动程序将尝试读取 {/ 1}}内的Clob流。因此,您必须在更新之前打开流,运行更新,然后关闭流 。
因此,我总是使用executeUpdate()
,然后使用:
select RPT_FILE ... for update
您可以使用方法替换 ResultSet rs = null;
try
{
rs = stmt.executeQuery ();
rs.next ();
Clob clob = rs.getClob (1);
clob.truncate (0);
clob.setString (1, data);
}
finally
{
rs = DBUtil.close (rs);
}
以将CLOB读取/写为流。这总是有效并且不会泄漏游标(因为Oracle的JDBC驱动程序中存在错误)。
但是密钥总是一样的:你必须从Oracle获得一个CLOB对象。永远不要试图自己创造其中一个。
答案 2 :(得分:0)
OTN有一些documentation on clob handling in Oracle JDBC可能会有所帮助。