【问题标题】:Executing a .sql file through Java通过 Java 执行 .sql 文件
【发布时间】:2015-03-21 00:07:15
【问题描述】:

我有一个 sql 脚本文件,我需要通过 java 执行其中的命令。我在互联网上搜索了同样的内容,我得到了一些定义解析器的代码来拆分 SQL 语句并执行它。但是它们都不适用于我的 sql 脚本文件。因为我的脚本文件同时包含 create 语句和结尾没有分号的 alter 语句[相反它有 GO]任何人都可以提出执行脚本文件的解决方案吗? 谢谢, 马赫什

【问题讨论】:

    标签: java sql


    【解决方案1】:

    对于简单的脚本,我通常使用来自 ibatis 的这个类 - ScriptRunner。或者,您可以从 Java 生成一个新的数据库客户端进程并输入您不想执行的脚本。这适用于所有脚本,因为 ScriptRunner 之类的简单解决方案在 sql 文件中的分隔符发生更改时无法正常工作。

    这是一个如何将 sql 作为字符串提供给生成的 db 客户端进程的示例:

    private void runSql(String pSql) {
            String tCommand = "mysql -u " + username + (password != null ? " -p" + password : "") + " " + dbName;
            System.out.println(tCommand);
    
            try {
                Process tProcess = Runtime.getRuntime().exec(tCommand);
                OutputStream tOutputStream = tProcess.getOutputStream();
                Writer w = new OutputStreamWriter(tOutputStream);
                System.out.println(pSql);
                w.write(pSql);
                w.flush();
    
                Scanner in = new Scanner(tProcess.getErrorStream());
    
                String errorMessage = "";
    
                while (in.hasNext()) {
                    errorMessage += in.next() + " ";
                }
    
                if (errorMessage.length() > 0) {
                    System.out.println(errorMessage);
                    throw new ClientSqlExecutionException(errorMessage);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    【讨论】:

    • 您好 Bozhidar,我有一个包含 MSSQL 查询的 sql 脚本文件。在MSSQL中通过命令提示符执行查询我们有Sqlcmd命令,,,Sqlcmd本身不能通过上面的代码工作!!!!
    • 你应该调整它的参数。我从未使用过它,但这种方法是通用的 - 使用正确的命令行参数它可以与任何数据库一起使用。
    • 嘿,谢谢Bozhidar,终于成功了!!!你提到的方法真的很通用!!!!
    【解决方案2】:

    看看 Mybatis Migrations 代码,它做了一些你需要的事情:

    http://code.google.com/p/mybatis/wiki/Migration

    【讨论】:

      【解决方案3】:

      您需要更改解析器,使其生成可执行语句。但我不确定我是否理解您所说的“通过 Java 执行”的意思。

      Java 不会执行那些 SQL 语句 - 您连接的数据库会执行。 Java 可以使用 JDBC 连接到数据库并从文件中发送 SQL 语句。

      我不明白为什么必须解析 SQL,除非您希望 Java 在将它们发送到数据库服务器之前对其进行验证。服务器将再次解析和验证它们,所以感觉就像你在白白做额外的工作。

      【讨论】:

        【解决方案4】:

        假设我理解您的问题,我可以向您提出的最简单的解决方案就是这个。

        1) 通过 Java IO 将文本文件读入字符串或数组。 2) 通过 JDBC 将字符串或数组传递给 MySQL。

        从文件中读取示例,

        import java.io.*;
        class FileRead 
        {
           public static void main(String args[])
          {
              try{
            // Open the file that is the first 
            // command line parameter
            FileInputStream fstream = new FileInputStream("textfile.txt");
            // Get the object of DataInputStream
            DataInputStream in = new DataInputStream(fstream);
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String strLine;
            //Read File Line By Line
            while ((strLine = br.readLine()) != null)   {
              // Print the content on the console
              System.out.println (strLine);
            }
            //Close the input stream
            in.close();
            }catch (Exception e){//Catch exception if any
              System.err.println("Error: " + e.getMessage());
            }
          }
        }
        

        http://www.roseindia.net/java/beginners/java-read-file-line-by-line.shtml获得

        【讨论】:

          【解决方案5】:

          最简单的方法是简单地获取语句并检查它们是否需要它们在末尾的半列:(这是一个示例,仅当它是逐行语句时才有效:

           public void executeScript(String script) {
             BufferedReader in  = new BufferedReader(new FileReader(script));
             while (in.read() > 0) {
               String statement = in.readLine();
               statement = statement.trim().toLowerCase();
               String command = statement.split("[ ]+")[0]; // split the statement.
          
               if (command.equals("insert") || command.equals("update") /* || any other */) {
                 statement = statement + ";";
               } 
          
               // execute statement using jdbc
             }
          }
          

          如果你不知道如何使用 jdbc,请问:-)

          【讨论】:

          • 嘿,谢谢 Pih,实际上我的脚本没有逐行语句,它有超过一行的语句!!!
          • 你有某种语句分隔符吗?可能会有所帮助。
          • 是的,它是“GO”,这是我的脚本文件内容:USE [guru] GO /****** 对象:表 [dbo].[Allowed_Countries] 脚本日期: 04/08/2011 17:22:40 ******/ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON SET ANSI_PADDING ON GO CREATE TABLE [dbo].[Allowed_Countries]( [CountryName] [varchar](100) NOT NULL , [CMName] [varchar](100) NOT NULL, [Allowed] [char](1) NOT NULL CONSTRAINT [DF_Allowed_Countries_Allowed] DEFAULT ('Y') ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo]。 [Allowed_Countries] 检查约束 [CK_Allowed_Countries] GO
          • 为什么你不滑行: statement.split("GO") ?并在这些“GO”中迭代?
          【解决方案6】:

          使用这个完全自包含的slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class,即您不需要任何第三方 jar 依赖项。

          可以将分隔符从; 更改为GO。我认为这应该可以解决问题。

          这是一个例子:

                  Reader reader = new BufferedReader(*** Your FileReader instance ***);
                  try
                  {
                      ScriptRunner runner = new ScriptRunner(connection, false, true);
                      runner.setDelimiter("GO", true);
                      runner.runScript(reader);
                  }
                  finally
                  {
                      reader.close();
                  }
          

          【讨论】:

          • 嗨乔纳斯,我试过上面的代码!!!它不工作。这是我的脚本:USE [guru] GO /****** Object: Table [dbo].[Allowed_Countries]脚本日期:04/08/2011 17:22:40 ******/ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON SET ANSI_PADDING ON GO CREATE TABLE [dbo].[Allowed_Countries]( [CountryName] [varchar](100 ) NOT NULL, [CMName] [varchar](100) NOT NULL, [Allowed] [char](1) NOT NULL 约束 [DF_Allowed_Countries_Allowed] DEFAULT ('Y') ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [ dbo].[Allowed_Countries] 检查约束 [CK_Allowed_Countries] GO
          【解决方案7】:

          Apache Ant SQL 任务为我工作。 https://ant.apache.org/manual/Tasks/sql.html

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-11-30
            • 2013-04-27
            • 1970-01-01
            • 2018-09-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多