SQL Parse

Olá, tenho um arquivo .sql com varios comandos, gostaria de executá-los usando JDBC, não consegui implementar um parser que funcionasse!!! Ainda não encontrei nenhum API que fizesse o que preciso. Alguem tem uma dica??

Cara baixa o projeto do jforum, derrepente é como tu quer implementar

http://www.jforum.net/download-source.jsp

Olá

Desculpe se não entendi direito mas para mim isto não faz sentido.

Este arquivo .sql é um script para rodar direto na base de dados?

Caso afirmativo, por que valeria a pena ler com Java, traduzir para JDBC, abrir conexão com o banco para depois executar no banco?

Qual banco de dados você usa que não tem um programinha de linha de comando para executar diretamente scripts na base de dados?

[]s
Luca

Respondendo ao último post, eu preciso que quando um usuario clique um botão, varias coisas sejam feitas automaticamente, e uma delas é a atualizaçao do bando de dados, tendo o .sql fornecido previamente, o usuário é pra ser burro, apenas clicar o botao.

wmilhomem, nao entendi como esse link poedria me ajudar, aquilo é outro forum?

Atencioamente,
Wilson

[quote=wilsoneto]Respondendo ao último post, eu preciso que quando um usuario clique um botão, varias coisas sejam feitas automaticamente, e uma delas é a atualizaçao do bando de dados, tendo o .sql fornecido previamente, o usuário é pra ser burro, apenas clicar o botao.

wmilhomem, nao entendi como esse link poedria me ajudar, aquilo é outro forum?

Atencioamente,
Wilson[/quote]

Dá uma olhada na classe Runtime e executa por ela o comando que insere os dados no arquivo direto no banco, chamando o programinha de linha do comando para seu SGDB.

Na verdade é o projeto deste forum q nos estamos utilizando.

Olá, vou experiementar esse projeto do JForum, mas wmilhomem, como vocês estão usando isso?! Preciso achar a ponta do durex pra puxar!!

Atenciosamente,
Wilson

Meu Deus!

Para que complicar tanto? Ou será que eu que não estou entendendo??? :frowning:

Carrega o arquivo, cria uma String com o conteúdo, passa para um Statement/PreparedStatement e executa.

Falow!

Olá

Com casca e tudo inclusive ponto e vírgula?

Já fiz um programa em 1999/2000 que executava scripts, migrava bases de dados e outras frescuras a mais. Usei os metadados do JDBC.

Acabei de procurar o tal programa e cheguei a óbvia conclusão de que somente para executar os scripts é melhor adotar a solução já indicada de executar pelo console. O meu programinha funcionava com só 3 bases de dados.

Só para sentirem como é mais complicado ler o script, separei e vou colocar aqui o programinha de scripts feito para o Java 1.1.6. Vejam o método ParseAndExecScript:

import java.sql.*;
import java.io.*;
import java.util.*;

public final class ExecuteScript
{
   // Lê o nome do arquivo script, do banco de dados, do data source, login e senha
   public static final String usage = "uso: java ExecuteScript " +
                         "ArquivoScript ArquivoCFGSistema";
   // O arquivo arqCFGSistema contém os dados da base de dados
   
   public static void main(String[] args)
        throws SQLException, ClassNotFoundException, IOException
   {

      if (args.length != 2)
      {
          System.err.println(usage);
          System.exit(1);
      }

      VerificaArquivos(args);

      BufferedReader br = new BufferedReader(new FileReader(args[0]));

      Connection conn = ExecuteScript.BuildConnection(args[1]);

      if (conn != null)
      {
         ExecuteScript.ParseAndExecScript(br, conn);

         conn.close();
      }
      else
      {
         System.err.println("Erro - conexão não efetuada");
         System.exit(4);
      }
      br.close();
   }

   private static void VerificaArquivos(String[] args)
   {
      File arqScript = new File(args[0]);

      if (! arqScript.exists())
      {
         System.out.println("Erro fatal - Arquivo com os scripts " +
                             args[0] + " não foi encontrado.");
         System.exit(2);
      }
      File arqCFGSistema = new File(args[1]);
      if (! arqCFGSistema.exists())
      {
         System.out.println("Erro fatal - Arquivo de configuração do sistema " +
                             args[1] + " não foi encontrado.");
         System.exit(3);
      }
   }

   private static Connection BuildConnection(String strArqCFGSistema)
        throws SQLException, ClassNotFoundException, IOException
   {
     Connection conexao = null;
     String sLine   = "",
            sDB     = "",
            sVS     = "",
            sURL    = "",
            sLogin  = "",
            sSenha  = "",
            sDriver = "";

     try
     {

       BufferedReader brCFGSistema = new BufferedReader(new FileReader(
                               strArqCFGSistema));

       sLine   = brCFGSistema.readLine();
       sLogin  = sLine.substring(6, sLine.length());

       sLine   = brCFGSistema.readLine();
       sSenha  = sLine.substring(6, sLine.length());
       sSenha  = undoKeyStr(sSenha);

       sLine   = brCFGSistema.readLine();
       sDB     = sLine.substring(3, sLine.length());

       sLine   = brCFGSistema.readLine();
       sVS     = sLine.substring(3, sLine.length());

       sLine   = brCFGSistema.readLine();
       sURL    = sLine.substring(4, sLine.length());

       sLine   = brCFGSistema.readLine();
       sDriver = sLine.substring(7, sLine.length());

       brCFGSistema.close();

       // tentar 3 vezes a conexão com o Banco de Dados
       // para o caso de problemas na rede
       for (int nTentativas = 0; nTentativas < 3; nTentativas++)
       {
          Class.forName(sDriver);
          conexao = DriverManager.getConnection(sURL, sLogin, sSenha);
          int j = 1;
          if (conexao != null)
             break;
       }

       if (conexao == null)
       {
         System.out.println("Erro fatal - \n" +
                            "A conexão com o Banco de Dados do Sistema" +
                            " não pode ser efetivada.\n" +
                            "Verifique se o banco existe ou se as " +
                            "configurações do Sistema estão corretas.");
         System.exit(3);
       }
     }
     catch(Exception ex)
     {
         ExecuteScript.printExceptions(ex);
     }

     return conexao;


   }

   // Desfaz a criptografia criada pelo metodo makeKey
   // Retorna o 2o. param. de makeKeyStr(senha) descriptografada
   // O parametro deve ser a string criptografada pelo metodo makeKeyStr

   private static String undoKeyStr ( String aCrypt )
   {
      // RETIRADO

      return acrypt;
   }

   private static void ParseAndExecScript(BufferedReader br, Connection conn)
        throws SQLException, ClassNotFoundException, IOException
   {
      
      StringBuffer commandSQL = new StringBuffer("");
      String line;
      String strSQL;
      int nLineLength;
      int nComandos = 0;
      int nCount = 0;
      int nLines = 0;

      String strResult = "";
      FileWriter arqEco = new FileWriter("ecoScript.txt", true);

      while ((line = br.readLine()) != null)
      {
         line = line.trim();
         nLineLength = line.length();
         arqEco.write(line+"\n", 0, nLineLength+1);   // Ecoa a linha
         if (nLineLength > 0)                   // Descarta linha em branco
         {
            if (!line.startsWith("#"))            // Descarta comentário
            {
               if (line.endsWith(";"))     // Fecha SQL, executa,
                                           // limpa comando e sai do loop
               {
                  // Qdo ; está no fim da linha,
                  // pode ser que o comando SQL ainda não tenha a linha
                  if (nLineLength > 1)
                  {
                     // Verifica o caso doido de vários ;s seguidas
                     while (line.endsWith(";"))
                     {
                        line = line.substring(0, nLineLength-1).trim();
                        nLineLength = line.length();
                     }
                     if (nLineLength > 0)
                     {
                        commandSQL.append(line);
                     }
                  }

                  strSQL = commandSQL.toString().trim();
                  // Só faz se se a string SQL não está vazia
                  // (evita erro no script = 2 ';'s seguidas)
                  if (strSQL.length() > 0)
                  {
                     try
                     {
                        Statement unknownSQL = conn.createStatement();

                        if (!unknownSQL.execute(strSQL))
                        {
                           nLines = unknownSQL.getUpdateCount();
                           strResult = nLines +
                                       " linha" + (nLines>0 ? "s" : "")
                                       + " atualizada"
                                       + (nLines>1 ? "s" : "");
                           arqEco.write(strResult+"\n", 0, strResult.length()+1);
                           System.out.println(strResult);
                           nCount += nLines;
                        }
                        unknownSQL.close();
                        nComandos++;
                     }
                     catch (SQLException eSQL)
                     {
                        ExecuteScript.printExceptions(eSQL, strSQL,
                                                      strResult, arqEco);
                        strResult = "\nAtenção - " +
                            "devido a erro na linha anterior\n" +
                            "A execução dos scripts será encerrada.";
                        arqEco.write(strResult+"\n", 0, strResult.length()+1);
                        System.out.println(strResult);
                        if (nComandos > 0)
                        {
                            strResult = "Processados " +
                                        " comando" +
                                        (nComandos>0 ? "s" : "");
                           arqEco.write(strResult+"\n", 0, strResult.length()+1);
                           System.out.println(strResult);
                        }
                        arqEco.close();
                        System.exit(3);
                     }
                  }
                  commandSQL.setLength(0);
               }
               else
               {
                  commandSQL.append(line + " ");
               }
            }
         }
      }
      if (nCount > 0)
      {
         strResult = "Processado" + (nComandos>0 ? "s " : " ") +
                            nComandos +
                            " comando" + (nComandos>0 ? "s" : "");
         arqEco.write(strResult+"\n", 0, strResult.length()+1);
         System.out.println(strResult);
         strResult = "Total de " + nCount +
                            " linha" + (nCount>1 ? "s" : "") +
                            " atualizada" + (nCount>1 ? "s" : "");
         arqEco.write(strResult+"\n", 0, strResult.length()+1);
         System.out.println(strResult);
      }
      arqEco.close();
   }

   private static void printExceptions(Exception e)
   {
      System.out.println("\nErro: " + e.getMessage());
   }

   private static void printExceptions(Exception e, String strSQL,
                                String strResult, FileWriter arqEco)
                                throws IOException
   {
      if (e instanceof SQLException)
      {
         while (e != null)
         {
            strResult = "\nExceção SQL: " + e.getMessage();
            arqEco.write(strResult+"\n", 0, strResult.length()+1);
            System.out.println(strResult);
//            System.out.println("ANSI-92 estado SQL: " + e.getSQLState());
//            System.out.println("Mensagem do driver: " + e.getErrorCode());
            e = ((SQLException)e).getNextException();
         }
         if (strSQL.length() > 0)
            strResult = "\nInstrução SQL: " + strSQL;
            arqEco.write(strResult+"\n", 0, strResult.length()+1);
            System.out.println(strResult);
       }
       else
       {
          strResult = "\nErro: " + e.getMessage();
          arqEco.write(strResult+"\n", 0, strResult.length()+1);
          System.out.println(strResult);
       }
   }
}

Sem críticas para a notação húngara porque naquela época a gente não adotava so Code Conventions da Sun que ainda nem existiam.

[]s
Luca

Olá

Ah, antes que eu me esqueça. Não usem este programinha como modelo de programação porque foi feito na maior pressão para apagar um “incêndio” em um cliente. Apesar de estar correto e funcionar direitinho, acho que para servir para alguma coisa precisaria de uma revisão.

[]s
Luca

Luca, realmente falei besteria hehe

É que eu já fiz uma aplicaçãozinha que só fazia seleções e funcionava na boa, não pensei em outras instruções.

Ok Luca, funcionou, Muito obrigado

eu ja executei codigos sql em java da seguinte forma
( no caso o banco era o postgresql , mas to usando pra exemplificar )

ProcessBuilder pb = new ProcessBuilder(new String[] {"createdb","sommrsd" + caso.getIdentificador(), "-U", "postgres"}); // 1 Map<String, String> env = pb.environment(); env.put("PGPASSWORD", "postgres"); // o password do banco o PGPASSWORD varia pra cada tipo de banco creio eu process = pb.start();

no caso ae em 1 estou executando um comando de linha de comando colocando os parametros um em cada posicao do array. no meu caso estava usando postgres, e tava criando um database dinamicamente o comando q isso ae ta chamando é se o identificador for 1 “createdb sommrsd1 -U postgres”,

pra dar dump

ProcessBuilder pb = new ProcessBuilder(new String[] {"pg_dump", "-i", "-h", "localhost", "-p", "5432", "-U","postgres", "-F", "c", "-f", "bckp/sommrsd" + caso.getIdentificador()+".sql","sommrsd"}); Map<String, String> env = pb.environment(); env.put("PGPASSWORD", "postgres"); process = pb.start();

dando restore

ProcessBuilder pb = new ProcessBuilder(new String[] {"pg_restore", "-d", "sommrsd" + caso.getIdentificador(),"bckp/sommrsd" + caso.getIdentificador() + ".sql","-U","postgres"}); Map<String, String> env = pb.environment(); env.put("PGPASSWORD", "postgres"); process = pb.start();