将一个 Clob 复制到另一个具有不同实现的 Clob

Copying a Clob in another Clob with different implementation

我们公司正在进行数据库迁移。由于很多原因,我们不能使用数据库迁移工具,所以我们不得不开发我们的迁移工具来将某些特定表中包含的所有行从一个数据库复制到另一个数据库。我们开发了一个使用多个数据库的 JDBC 的工具。目前,我们正在从 DB2 迁移到 Oracle,中间有一个到 H2 的步骤。相同的表有一个 Clob 列。当我们将此列从 DB2 导出到 H2 时,我们没有遇到任何错误或问题,但是当我们尝试使用 JDBC 将 Clob 从 H2 复制到 Oracle 时,我们会遇到以下异常:

ClassCastException: cannot cast from org.h2.jdbc.JdbcClob to oracle.jdbc.Clob

有没有一种方法或程序可以执行这种转换?像不同 Clob 类型中的 ClobCopy 实用程序之类的东西?不幸的是,我们只能使用 Java 和 Jdbc 来完成这项任务,由于客户的规格,没有 JPA 或数据库迁移工具。

这是我尝试做的一个例子:

public class CopyTable {

    public void doCopy(){
        Connection h2 = getH2Connection(); //suppose this exists and works
        Connection oracle = getOracleConnection(); //suppose this exists and works

        String sqlSelect = "select * from tabletoexport";
        String sqlInsert = "insert into tabletofill(ID, DATA) values (?,?)";

        PreparedStatement select = h2.prepareStatement(sqlSelect);
        PreparedStatement insert = oracle.prepareStatement(sqlInsert);
        ResultSet rs = select.executeQuery();
        while (rs.next()){
            insert.setLong(1, rs.getLong("ID"));
            insert.setClob(2, rs.getClob("DATA")); //this throws an exception
            insert.executeUpdate();
        }

    }

}

采用 ReaderClob interface has a getCharacterStream() method which returns a Reader, and the PreparedStatement interface has a setClob() 方法。要使副本正常工作,您需要做的就是使用这些方法。

换句话说,替换行

    insert.setClob(2, rs.getClob("DATA")); //this throws an exception

    insert.setClob(2, rs.getClob("DATA").getCharacterStream());

至于为什么从 DB/2 到 H2 的导入没有报错,也许 H2 JDBC 驱动程序没有假设 Clob 值传递给 setClob 来自 H2,但 Oracle JDBC 驱动程序确实假定以相同方式传入的 Clobs 来自 Oracle。但是,Oracle JDBC 无法合理地对 Reader 做出任何此类假设,因为这些假设可能来自任何地方