如何在java中执行sql-script文件?

我想在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(); } } } 
  • 代码示例是从这里提取出来的,并被修改为回答问题,假设用户想要执行PostgreSQL脚本文件。

只要你不介意依赖于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(); } 

不,您必须读取该文件,将其拆分为单独的查询,然后单独执行(或使用JDBC的批处理API)。

其中一个原因是每个数据库都定义了自己的SQL语句分离方式(一些使用;另一些允许二者甚至定义自己的分隔符)。

你不能使用JDBC,因为它不支持。 Scriptrunner办法将包括iBatis iBATIS是一个持久性框架,并调用iBatis文档中显示的Scriptrunner构造函数。

它不是很好,包括像ibatis这样一个重量级的持久性框架,以便运行一个简单的SQL脚本,你可以使用命令行

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

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进行版本化,所以如果只调用了迁移,那么只有那些尚未运行的脚本才能运行。 使用名为“schema_version”的表来跟踪事物。 但也可以做其他事情,看文档: 飞路 。

干净的调用不是必需的,但从干净的数据库开始很有用。 另外,要注意位置(默认是“classpath:db / migration”),在':'之后没有空格,那个人把我抓出来了。

由于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()); } } 

我发现最简单的外部工具也是可移植的是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不支持这个选项(尽pipe一个特定的数据库驱动可能会提供这个)。 无论如何,将所有文件内容加载到内存中都不会有问题。

试试这个代码:

 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()); }