40

ファイルの内容全体を大きなクエリに読み込んで実行せずに、SQL スクリプト ファイルを Java で実行したいと考えています。

他の標準的な方法はありますか?

4

12 に答える 12

32

Ant に依存することを気にしない限り、Java から SQL スクリプトを自分で読まずに実行する優れた方法があります。私の意見では、あなたの場合、そのような依存関係は非常に正当化されます。SQLExec クラスが 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();
}
于 2010-06-16T15:56:51.360 に答える
22

それを行う移植可能な方法はありません。ただし、ネイティブクライアントを外部プログラムとして実行して、それを行うことができます:

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();
    }
  }
}
  • コード サンプルはここから抽出され、ユーザーが PostgreSQL スクリプト ファイルを実行することを想定して質問に答えるように変更されています。
于 2010-01-15T13:22:10.307 に答える
10

Flyway ライブラリはこれに非常に適しています。

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

これにより、スクリプトの場所がスキャンされ、順番に実行されます。スクリプトは V01__name.sql でバージョン管理できるため、migrate だけが呼び出された場合、まだ実行されていないスクリプトのみが実行されます。物事を追跡するために「schema_version」と呼ばれるテーブルを使用します。ただし、他のこともできます。ドキュメントを参照してください: flyway

clean 呼び出しは必須ではありませんが、クリーンな DB から開始すると便利です。また、場所 (デフォルトは「classpath:db/migration」) に注意してください。「:」の後にスペースがありません。

于 2016-10-07T08:25:11.377 に答える
6

いいえ、ファイルを読み取り、個別のクエリに分割してから、個別に(またはJDBCのバッチAPIを使用して)実行する必要があります。

その理由の1つは、すべてのデータベースがSQLステートメントを分離する独自の方法を定義していることです(使用する;もの/もあれば、両方を許可するものもあれば、独自のセパレーターを定義することさえできるものもあります)。

于 2010-01-15T13:19:23.620 に答える
3

JDBCはをサポートしていないため、JDBCを使用することはできません。回避策は、iBatisを含めることです。iBATISは永続性フレームワークであり、 iBatisのScriptrunnerドキュメントに示されているようにコンストラクターを呼び出し ます。

コマンドラインを使用して実行できる任意の方法で単純なSQLスクリプトを実行するために、ibatisのような重量のある永続性フレームワークを含めるのは良くありません。

$ mysql -u root -p db_name < test.sql
于 2010-01-15T13:46:18.797 に答える
3

JDBC はこのオプションをサポートしていないため、この問題を解決する最善の方法は、Java プログラムを介してコマンド ラインを実行することです。以下は、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());
      }
}
于 2012-03-07T12:05:46.823 に答える
0

JDBCはこのオプションをサポートしていません(ただし、特定のDBドライバーがこれを提供する場合があります)。とにかく、すべてのファイルの内容をメモリにロードすることに問題はないはずです。

于 2010-01-15T13:20:07.223 に答える
0

このコードを試してください:

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());  
}
于 2010-12-06T13:58:56.940 に答える