在我的DB2数据库中,我有一个带Blob的表:
CREATE TABLE FILE_STORAGE (
FILE_STORAGE_ID integer,
DATA blob(2147483647),
CONSTRAINT PK_FILE_STORAGE PRIMARY KEY (FILE_STORAGE_ID));
使用db2jcc JDBC驱动程序(db2jcc4-9.7.jar),我可以毫无问题地在此表中读写数据。
现在我需要能够追加数据到现有行,但DB2会给出神秘错误
Invalid operation: setBinaryStream is not allowed on a locator or a reference. ERRORCODE=-4474, SQLSTATE=null
我使用以下代码附加我的数据:
String selectQuery = "SELECT DATA FROM FILE_STORAGE WHERE FILE_STORAGE_ID = ?";
try (PreparedStatement ps = conn.prepareStatement(selectQuery, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
ps.setInt(1, fileStorageID);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
Blob existing = rs.getBlob(1);
try {
// The following line throws the exception:
try (OutputStream output = existing.setBinaryStream(existing.length() + 1)) {
// append the new data to the output:
writeData(output);
} catch (IOException e) {
throw new IllegalStateException("Error writing output stream to blob", e);
}
rs.updateBlob(1, existing);
rs.updateRow();
} finally {
existing.free();
}
} else {
throw new IllegalStateException("No row found for file storage ID: " + fileStorageID);
}
}
}
我的代码正在使用OutputStream to the BLOB column of a DB2 database table中建议的方法。似乎还有其他人遇到同样的问题:Update lob columns using lob locator。
作为解决方法,我目前将所有现有数据读入内存,将新数据附加到内存中,然后将完整数据写回blob。这有效,但速度非常慢,显然如果blob中有更多数据需要更长的时间,每次更新都会变慢。
我确实需要使用Java来更新数据,但除了切换到JVM之外,我很乐意尝试任何可能的替代方案,我只需要以某种方式附加数据。
提前感谢任何想法!
答案 0 :(得分:2)
如果您只需要将数据附加到BLOB列的末尾并且不想将整个值读入您的程序,那么简单的UPDATE
语句将更快,更直接。
您的Java程序可以通过executeUpdate()
运行:
UPDATE file_storage SET data = data || BLOB(?) WHERE file_storage_id = ?
此参数标记将由setBlob(1, dataToAppend)
和setInt(2, fileStorageID)
填充。