简体   繁体   中英

Append data to a DB2 blob

In my DB2 database, I have a table with a Blob:

CREATE TABLE FILE_STORAGE (
    FILE_STORAGE_ID integer,
    DATA blob(2147483647),
    CONSTRAINT PK_FILE_STORAGE PRIMARY KEY (FILE_STORAGE_ID));

Using the db2jcc JDBC driver (db2jcc4-9.7.jar), I can read and write data in this table without any problems.

Now I need to be able to append data to existing rows, but DB2 gives the cryptic error

Invalid operation: setBinaryStream is not allowed on a locator or a reference. ERRORCODE=-4474, SQLSTATE=null

I use the following code to append my data:

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);
        }
    }
}

My code is using the methods as suggested in OutputStream to the BLOB column of a DB2 database table . There also seem to be other people who have the same problem: Update lob columns using lob locator .

As a workaround , I currently read all the existing data into memory, append the new data in memory, and then write the complete data back into the blob. This works, but it's very slow and obviously it will take longer if there's more data in the blob, getting slower with each update.

I do need to use Java to update the data, but apart from switching away from the JVM, I am happy to try any possible alternatives at all, I just need to append the data somehow.

Thanks in advance for any ideas!

If you only need to append data to the end of a BLOB column and don't want to read the entire value into your program, a simple UPDATE statement will be faster and more straightforward.

Your Java program could run something like this via executeUpdate() :

UPDATE file_storage SET data = data || BLOB(?) WHERE file_storage_id = ?

The parameter markers for this would be populated by setBlob(1, dataToAppend) and setInt(2, fileStorageID) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM