Мне нравится копировать некоторые таблицы в свою 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.
Нужно ли мне l oop for ( int c = 1; c <= rsmd.getColumnCount(); c++ )
для каждой строки или есть какой-то более быстрый способ сделать это?
Это возможно и полезно для чтения исходных таблиц пакетами, а не построчно с while ( rs.next() )
?
Обратите внимание, простой INSERT INTO D_NR_COPY (...) SELECT ... FROM D_NR
не работает, потому что исходная база данных не является базой данных Oracle.