Execute sql statement via JDBC with CLOB binding

↘锁芯ラ 提交于 2019-12-08 06:37:40

问题


I have the following query (column log is of type CLOB):

UPDATE table SET log=? where id=?

The query above works fine when using the setAsciiStream method to put a value longer than 4000 characters into the log column.

But instead of replacing the value, I want to append it, hence my query looks like this:

UPDATE table SET log=log||?||chr(10) where id=?

The above query DOES NOT work any more and I get the following error:

java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column

回答1:


It looks to me like you have to use a PL/SQL block to do what you want. The following works for me, assuming there's an entry with id 1:

import oracle.jdbc.OracleDriver;
import java.sql.*;
import java.io.ByteArrayInputStream;

public class JDBCTest {

    // How much test data to generate.
    public static final int SIZE = 8192;

    public static void main(String[] args) throws Exception {

        // Generate some test data.
        byte[] data = new byte[SIZE];
        for (int i = 0; i < SIZE; ++i) {
            data[i] = (byte) (64 + (i % 32));
        }

        ByteArrayInputStream stream = new ByteArrayInputStream(data);

        DriverManager.registerDriver(new OracleDriver());
        Connection c = DriverManager.getConnection(
            "jdbc:oracle:thin:@some_database", "user", "password");

        String sql =
            "DECLARE\n" +
            "  l_line    CLOB;\n" +
            "BEGIN\n" +
            "  l_line := ?;\n" +
            "  UPDATE table SET log = log || l_line || CHR(10) WHERE id = ?;\n" +
            "END;\n";

        PreparedStatement stmt = c.prepareStatement(sql);
        stmt.setAsciiStream(1, stream, SIZE);
        stmt.setInt(2, 1);
        stmt.execute();
        stmt.close();

        c.commit();

        c.close();
    }
}



回答2:


BLOBs are not mutable from SQL (well, besides setting them to NULL), so to append, you would have to download the blob first, concatenate locally, and upload the result again.

The usual solution is to write several records to the database with a common key and a sequence which tells the DB how to order the rows.



来源:https://stackoverflow.com/questions/678060/execute-sql-statement-via-jdbc-with-clob-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!