Con questo breve post cerchero’ di descrivere in modo veloce e sintetico un possibile sistema per effettuare la copia dei dati da una tabella ad un’altra, magari su macchine differenti e magari su db server diversi.
Il sistema che descrivo in seguito e’ solo una traccia e logicamente deve essere migliorato, serve unicamente a dare le basi a chi si avvicina per la prima volta a questo problema cosi da poterlo affrontare con un po’ piu’ di serenita’
Livello:
Facile
Per chi:
Principiante
Scenario:
Copiare i dati di una tablla MySql in una su MsSql
Premessa:
E’ importante far presente che per questo esempio si fa riferimento a due tabelle di identica struttura sia nei nomi di campo che nei tipi
Dato per assunto che abbiate gia’ due oggeti Connection:
// connessione al db sorgente Connection srcConnection; // connessione al db destinazione Connection dstConnection;
iniziamo a prelevare le informazioni sulle colonne della nostra tabella “sorgente” in questo modo:
DatabaseMetaData dmd = srcConnection.getMetaData(); ResultSet columns = dmd.getColumns(null, "%", "tbl_src", "%");
a questo punto in columns abbiamo tutto quello che serve per poter creare le stringhe da utilizzare in un PreparedStatement, quindi agiremo cosi:
// preparo 2 StringBuffer che conterranno i tipici // capo1,campo2,campo3 con i rispettivi ?,?,? StringBuffer clNames = new StringBuffer(); StringBuffer clValues = new StringBuffer(); // un contatore per il numero di colonne // ci sono altri modi piu' 'giusti' per fare questo ;) int nColumns = 0; // ciclo sul resultset ottenuto in precedenza contenente tutte // le informazioni sulle colonne della mia tabella while(columns.next()) { // prendo il nome della colonna che sto ciclando String columnName = columns.getString("COLUMN_NAME"); // creo le basi per il preparedstatement clNames.append(columnName); clValues.append("?"); // verifico se mi trovo all'ultima colonna cosi da // non mettere piu' la virgola if (!columns.isLast()) { clNames.append(","); clValues.append(","); } nColumns++; }
a questo punto prepariamo il preparedstatement che ci servira’ per eseguire le insert nella tabella di destinazione
String query = String.format("INSERT INTO %s (%s) VALUES (%s)", "tbl_dest", clNames.toString(), clValues.toString()); PreparedStatement pstmtDest = dstConnection.prepareStatement(query);
fatto questo possiamo semplicemente prendere tutti i record dalla tabella sorgente ed inserirli nella nuova tabella
// prendo tutti i record dalla tabella sorgente Statement stmtSrc = srcConnection.createStatement(); ResultSet rsetSrc = stmt.executeQuery("SELECT * FROM tbl_src"); // ciclo i tutti i record while(rset.next()) { for(int i = 1; i <= nColumns; i++) { // assegno colonna per colonna i valori del sorgente // sul preparedstatemnt della destinazione pstmtDest.setObject(i, rsetSrc.getObject(i)); } // inserisco la riga nella tabella di destinazione pstmtDest.executeUpdate(); }
et voila’, i record sono stati copiati correttamente anche se le nostre tabelle erano su db server differenti.
Un altro sistema nel caso in cui la SELECT avesse dei campi specifici e’ quello di farsi dare le colonne direttamente dal resultset della query in questo modo:
ResultSet rsetSrc = stmt.executeQuery("SELECT campo1,campo2 FROM tbl_src"); ResultSetMetaData rsmd = rsetSrc.getMetaData(); for(int columnCounter = 1; columnCounter <= rsmd.getColumnCount(); columnCounter++) { String fieldName = rsmd.getColumnName(columnCounter); // qui andremo ad inserire lo StringBuffer // per preparare le stringhe necessarie // al il PreparedStatement come e' stato fatto sopra }
Logicamente questa e’ una situazione assolutamente base, le problematiche tipiche che si incontrano possono essere quella di creare runtime la tabella di destinazione, avere i nomi dei campi che non hanno corrispondenza, join tra tabelle etc etc… ma questo e’ un altro discroso che magari affrontero’ un altro giorno.
Con questo sistema, che e’ uno dei primi che ho utilizzato, ho copiato diversi milioni di record da mysql, mssql, postgresql e oracle e con una buona connessione tra le macchine e un discreto hardware ho ottenuto anche buoni risultati in termini di tempo.
Spero che questo mini post vi possa essere stato d’aiuto quantomeno per individuare la strada, perche’ sicuramente la forma va modificata, e per aver visto gli oggetti che entrano in gioco.
Ciao e alla prossima,
Cristian.
RSS feed for comments on this post · TrackBack URI
Leave a reply
You must be logged in to post a comment.