Voglio eseguire un file di script SQL in Java senza leggere tutto il contenuto del file in una grossa query ed eseguirlo. C'è un modo standard?Come eseguire il file sql-script in java?
risposta
Non esiste un modo portatile per farlo. È possibile eseguire un client nativo come un programma esterno per farlo però:
import java.io.*;
public class CmdExec {
public static void main(String argv[]) {
try {
String line;
Process p = Runtime.getRuntime().exec
("psql -U username -d dbname -h serverhost -f scripfile.sql");
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
}
catch (Exception err) {
err.printStackTrace();
}
}
}
- Esempio di codice è stato estratto dai here e modificato per rispondere alla domanda partendo dal presupposto che l'utente vuole eseguire un file di script di PostgreSQL.
No, è necessario leggere il file, dividerlo in query separate e quindi eseguirle singolarmente (o utilizzando l'API batch di JDBC).
Uno dei motivi è che ogni database definisce il proprio modo di separare le istruzioni SQL (alcuni usano ;
, altri /
, alcuni consentono entrambi o anche di definire il proprio separatore).
JDBC non supporta questa opzione (sebbene un driver DB specifico possa offrire questo). Ad ogni modo, non dovrebbe esserci un problema con il caricamento di tutti i contenuti del file in memoria.
Non è possibile utilizzare JDBC poiché non supporta. Il lavoro dovrebbe essere incluso iBatis iBATIS è un framework di persistenza e chiamare il costruttore Scriptrunner
come mostrato nella documentazione iBatis.
La sua non è bene includere un framework di persistenza peso pesante come ibatis al fine di eseguire un semplice script SQL eventuali modi che si può fare utilizzando riga di comando
$ mysql -u root -p db_name < test.sql
C'è grande modo di eseguire script SQL da Java senza leggerli da soli fino a quando non ti dispiace avere una dipendenza da Ant. A mio avviso, una tale dipendenza è molto ben giustificata nel tuo caso. Ecco il codice di esempio, dove la classe SQLExec vive in ant.jar:
private void executeSql(String sqlFilePath) {
final class SqlExecuter extends SQLExec {
public SqlExecuter() {
Project project = new Project();
project.init();
setProject(project);
setTaskType("sql");
setTaskName("sql");
}
}
SqlExecuter executer = new SqlExecuter();
executer.setSrc(new File(sqlFilePath));
executer.setDriver(args.getDriver());
executer.setPassword(args.getPwd());
executer.setUserid(args.getUser());
executer.setUrl(args.getUrl());
executer.execute();
}
Ho provato questo per alcuni dei miei script Oracle Oracle, funziona per 'insert',' create table'. Ma per lo script che ha 'create o sostituisci trigger 'fallisce con ** java.sql.SQLSyntaxErrorException: ORA-00900: istruzione SQL non valida ** –
Forse dovresti considerare i tuoi delimitatori – carpinchosaurio
provare questo codice:
String strProc =
"DECLARE \n" +
" sys_date DATE;"+
"" +
"BEGIN\n" +
"" +
" SELECT SYSDATE INTO sys_date FROM dual;\n" +
"" +
"END;\n";
try{
DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
Connection connection = DriverManager.getConnection ("jdbc:oracle:thin:@your_db_IP:1521:your_db_SID","user","password");
PreparedStatement psProcToexecute = connection.prepareStatement(strProc);
psProcToexecute.execute();
}catch (Exception e) {
System.out.println(e.toString());
}
Il tuo esempio è eccessivamente semplicistico. Un 'Statement' di solito può eseguire solo una dichiarazione SQL alla volta. La domanda implica che ci siano un numero elevato di query o inserimenti coinvolti e che pertanto devono essere suddivisi in singole affermazioni trovando i separatori. – BoffinbraiN
Concordato, questa soluzione non funzionerà su script multi-statement. Usa jisql come suggerito di seguito. –
Poiché JDBC non supporta questa opzione il modo migliore per risolvere questo problema è l'esecuzione del comando linee tramite il programma Java. Bellow è un esempio a PostgreSQL:
private void executeSqlFile() {
try {
Runtime rt = Runtime.getRuntime();
String executeSqlCommand = "psql -U (user) -h (domain) -f (script_name) (dbName)";
Process pr = rt.exec();
int exitVal = pr.waitFor();
System.out.println("Exited with error code " + exitVal);
} catch (Exception e) {
System.out.println(e.toString());
}
}
Il tutorial di seguito aiuta ad eseguire sql
.
http://www.mkyong.com/jdbc/how-to-run-a-mysql-script-using-java/
biblioteca Flyway è veramente buono per questo:
Flyway flyway = new Flyway();
flyway.setDataSource(dbConfig.getUrl(), dbConfig.getUsername(), dbConfig.getPassword());
flyway.setLocations("classpath:db/scripts");
flyway.clean();
flyway.migrate();
Questo analizza le posizioni per gli script e li esegue in ordine. Gli script possono essere versionati con V01__name.sql, quindi se viene chiamata solo la migrazione, verranno eseguiti solo quelli non ancora eseguiti. Usa una tabella chiamata 'schema_version' per tenere traccia delle cose. Ma può fare anche altre cose, vedi i documenti: flyway.
La chiamata pulita non è necessaria, ma utile per iniziare da un DB pulito. Inoltre, sii consapevole della posizione (l'impostazione predefinita è "classpath: db/migration"), non c'è spazio dopo ":", quello mi ha sorpreso.
Il più semplice strumento esterno che ho trovato che sia anche portatile è jisql - https://www.xigole.com/software/jisql/jisql.jsp. Lo avresti eseguito come:
java -classpath lib/jisql.jar:\
lib/jopt-simple-3.2.jar:\
lib/javacsv.jar:\
/home/scott/postgresql/postgresql-8.4-701.jdbc4.jar
com.xigole.util.sql.Jisql -user scott -password blah \
-driver postgresql \
-cstring jdbc:postgresql://localhost:5432/scott -c \; \
-query "select * from test;"
Ho usato 'java -classpath lib/jisql-2.0.11.jar: lib/jopt-simple-3.2.jar: lib/javacsv.jar: ../ojdbc7.jar com.xigole.util.sql.Jisql -user ecm -password TODO -driver oracle.jdbc.OracleDriver -cstring jdbc: oracle: thin: @localhost: 1521: XE -c \; -input myoracle.sql' e ha funzionato perfettamente. –
ibatis suona bene per questo compito! – felipecrp