【发布时间】:2020-10-29 23:14:23
【问题描述】:
我喜欢将一些表复制到我的Oracle数据库中,所以我写了这个Java方法:
public static int copyTable (String cmdSelect, String cmdInsert, String sourceURL) throws SQLException {
int rowCount = 0;
try {
Connection conOra = DriverManager.getConnection("jdbc:default:connection:");
Connection conGauss = DriverManager.getConnection(sourceURL, "username", "password");
PreparedStatement sthSel = conGauss.prepareStatement(cmdSelect);
PreparedStatement sthIns = conOra.prepareStatement(cmdInsert);
ResultSet rs = sthSel.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
while ( rs.next() ) {
for( int c = 1; c <= rsmd.getColumnCount(); c++ ) {
sthIns.setObject(c, rs.getObject(c), rsmd.getColumnType(c), rsmd.getScale(c));
}
sthIns.addBatch();
rowCount++;
if (rowCount % 10000 == 0) {
sthIns.executeBatch();
}
}
sthIns.executeBatch();
rs.close();
sthSel.close();
sthIns.close();
conGauss.close();
conOra.close();
}
catch (SQLException e) {
throw e;
}
return rowCount;
}
我在 Oracle 中创建了函数
CREATE OR REPLACE FUNCTION copyTable(cmdSelect VARCHAR2, cmdInsert VARCHAR2, sourceURL VARCHAR2) RETURN NUMBER
AS LANGUAGE JAVA NAME 'Gauss.copyTable(java.lang.String, java.lang.String, java.lang.String) return int';
我这样称呼它:
DECLARE
cmdSelect VARCHAR2(1000) := 'SELECT NRID, NEID, NRNAME, NR_NAME, NBTYPE, NETYPE, GNODEBID, INVALIDTIME, OBJECTSTATUS FROM D_NR';
cmdInsert VARCHAR2(1000) := 'INSERT INTO D_NR_COPY (NRID, NEID, NRNAME, NR_NAME, NBTYPE, NETYPE, GNODEBID, INVALIDTIME, OBJECTSTATUS) VALUES (?,?,?,?,?,?,?,?,?)';
ret INTEGER;
BEGIN
ret := copyTable(cmdSelect, cmdInsert, 'some URL');
DBMS_OUTPUT.PUT_LINE ( 'ret = ' || ret );
COMMIT;
END;
我的第一次测试运行良好,程序按预期运行。但是我有点担心性能,有些表会比较大。我对Java一无所知。
我必须为每一行循环for ( int c = 1; c <= rsmd.getColumnCount(); c++ ) ,还是有更快的方法?
使用while ( rs.next() )分批读取源表而不是逐行读取是否可行且有益?
注意,普通的INSERT INTO D_NR_COPY (...) SELECT ... FROM D_NR 不起作用,因为源数据库不是 Oracle 数据库。
【问题讨论】:
-
您不能创建指向源数据库的数据库链接吗?使用数据库链接的单个插入选择 sql 会快得多
-
@SayanMalakshinov 不,数据库链接到非 Oracle 是不可能的。您可以使用“Oracle Database Gateway for ODBC”,但是源数据库是华为 GaussDB,而我们的 Oracle 在 Redhat Linux 上运行。由于特朗普/美国的禁令,华为可能不会在 Redhat 上为其 DB 提供 ODBC 驱动程序,同样适用于 Windows。将我们的 Oracle 迁移到另一个 Linux(例如 Suse Linux)也不是一种选择。
标签: java oracle performance dynamic-sql