Frage

Ich möchte eine SQL-Skriptdatei in Java ausführen, ohne den gesamten Dateiinhalt in eine große Abfrage zu lesen und es ausgeführt wird.

Gibt es eine andere Standardmethode?

War es hilfreich?

Lösung

Es gibt keine tragbare Art und Weise, dies zu tun. Sie können einen nativen Client als externes Programm ausführen, obwohl zu tun:

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();
    }
  }
}
  • Code-Probe wurde extrahiert aus hier und Antwort Frage geändert davon aus, dass die Benutzer möchte eine PostgreSQL-Skript-Datei auszuführen.

Andere Tipps

Es gibt gute Möglichkeit, SQL-Skripte von Java auszuführen, ohne sie selbst so lange zu lesen, wie es Ihnen nichts ausmacht eine Abhängigkeit von Ant haben. Meiner Meinung nach eine solche Abhängigkeit ist sehr gut in Ihrem Fall gerechtfertigt. Hier ist Beispielcode, wo SQLExec Klasse lebt 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();
}

Flyway Bibliothek ist wirklich gut für diese:

    Flyway flyway = new Flyway();
    flyway.setDataSource(dbConfig.getUrl(), dbConfig.getUsername(), dbConfig.getPassword());
    flyway.setLocations("classpath:db/scripts");
    flyway.clean();
    flyway.migrate();

Dieser scannt die Standorte für Skripte und führt sie in Ordnung. Skripte können mit V01__name.sql versioniert werden also, wenn nur die Migrate dann aufgerufen wird, nur diejenigen, die nicht bereits laufen ausgeführt werden. Verwendet eine Tabelle ‚SCHEMA_VERSION‘ genannt Spur der Dinge zu halten. Aber kann auch andere Dinge tun, sehen Sie die Dokumentation. flyway

Der saubere Anruf nicht erforderlich ist, aber nützlich aus einer sauberen DB zu starten. Auch bewusst sein, die Lage (Standard ist „Classpath: db / Migration“), gibt es keinen Raum nach dem ‚:‘., Dass man erwischt mich

Nein, müssen Sie die Datei lesen, spaltete es in separate Abfragen und sie dann einzeln ausführen (oder mit der Batch-API von JDBC).

Einer der Gründe dafür ist, dass jede Datenbank ihre eigene Art und Weise zu trennen SQL-Anweisungen definiert (einige Verwendung ;, andere /, einige erlauben beide oder sogar Ihr eigenes Trennzeichen zu definieren).

Sie können nicht mit JDBC tun, da es nicht unterstützt. Umgehen einschließlich würde iBatis iBATIS ein Persistenz-Framework und rufen Sie den Konstruktor Scriptrunner wie in iBatis Dokumentation.

Es ist nicht gut, ein schweres Gewicht Persistenzframework wie ibatis aufzunehmen, um eine einfache SQL-Skripte irgendwelche Möglichkeiten zu laufen, die Sie tun können, mit der Befehlszeile

$ mysql -u root -p db_name < test.sql

Da JDBC nicht diese Option nicht unterstützt, der beste Weg, diese Frage zu lösen, ist Befehlszeilen über das Java-Programm ausgeführt wird. Bellow ist ein Beispiel für 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());
      }
}

Das einfachste externe Tool, dass ich gefunden, die auch tragbar ist jisql - https: // www.xigole.com/software/jisql/jisql.jsp . Sie liefe es so:

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;"

JDBC diese Option nicht unterstützen (obwohl eine bestimmte DB-Treiber bieten kann). Wie auch immer, es sollte kein Problem mit dem Laden alle Dateiinhalt in den Speicher sein.

Versuchen Sie diesen Code ein:

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());  
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top