JavaでSQLスクリプトファイルを実行します。ファイルの内容全体を大きなクエリに読み込んで実行することはありません。
他の標準的な方法はありますか?
ポータブルな方法はありません。ただし、ネイティブクライアントを外部プログラムとして実行して、それを行うことができます。
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();
}
}
}
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();
}
フライウェイライブラリはこれに非常に適しています。
Flyway flyway = new Flyway();
flyway.setDataSource(dbConfig.getUrl(), dbConfig.getUsername(), dbConfig.getPassword());
flyway.setLocations("classpath:db/scripts");
flyway.clean();
flyway.migrate();
これにより、スクリプトの場所がスキャンされ、順番に実行されます。スクリプトはV01__name.sqlでバージョン管理できるため、移行のみが呼び出されると、まだ実行されていないスクリプトのみが実行されます。 'schema_version'というテーブルを使用して、物事を追跡します。しかし、他のこともできます。ドキュメントを参照してください: flyway 。
クリーンコールは必須ではありませんが、クリーンなDBから開始するのに役立ちます。また、場所(デフォルトは「classpath:db/migration」)に注意してください。「:」の後にスペースがありません。
いいえ、ファイルを読み取って個別のクエリに分割し、個別に実行する(またはJDBCのバッチAPIを使用する)必要があります。
理由の1つは、すべてのデータベースがSQLステートメントを分離する独自の方法を定義していることです(一部は;
、その他/
、いくつかは、両方を許可するか、独自のセパレータを定義することさえできます)。
JDBCはサポートしていないため、JDBCを使用することはできません。回避策はiBatisを含めることですiBATISは永続化フレームワークであり、 iBatis documentationに示すようにScriptrunner
コンストラクターを呼び出します。
コマンドラインを使用して簡単なSQLスクリプトを実行するために、ibatisのような重い永続性フレームワークを含めるのは良くありません
$ mysql -u root -p db_name < test.sql
JDBCはこのオプションをサポートしていないため、この問題を解決する最善の方法は、Java Program。Bellowは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());
}
}
ポータブルであることがわかった最も簡単な外部ツールはjisql- https://www.xigole.com/software/jisql/jisql.jsp です。次のように実行します。
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はこのオプションをサポートしていません(ただし、特定のDBドライバーがこれを提供する場合があります)。とにかく、すべてのファイルの内容をメモリにロードしても問題はないはずです。
このコードを試してください:
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());
}