Dúvida ao gerar arquivo de exportação em MySQL

6 respostas
dahenz

Bom dia!

Estou tentando gerar um arquivo de exportação em .txt de uma tabela do meu MySQL.

Meu código de exemplo é o seguinte:

select RPAD(sspc.dsHistorico,255,' '),
              LPAD(sspc.tpDocumento,2,' '),
              LPAD(sspc.nrDocumento,20,0)
     from tabela sspc

INTO OUTFILE 'c:/totem/prestacoes.txt' FIELDS TERMINATED BY '|' LINES TERMINATED BY '\r\n'

O problema é o seguinte:

O arquivo gera sem problemas algumas linhas.. porém outras o pipe "|" é retraído no campo sspc.dsHistorico uma ou duas colunas, eu acho que o mysql se perde pois o campo possui 255 caracteres e é do tipo VARCHAR(255), tentei mudar para CHAR(255) mas nao resolve.....

Alguém passou por isso???? Obrigado

6 Respostas

davidbuzatto

Pq vc não usa o mysqldump?

dahenz

na verdade esse é um comando que o usuario vai executar via sistema…

eu consigo usar o dump pra gerar um arquivo txt??? para importar para outro sistema???

Obrigado David!

davidbuzatto

Consegue sim.
Acabei de montar um exemplo aqui.
Dê uma olhada.

Lembre-se que você precisa adicionar o caminho do bin do MySQL na variável PATH do SO.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Classe com métodos para executar o dump do MySQL.
 * O "bin" do MySQL deve estar no PATH do SO.
 *
 * @author David Buzatto
 */
public class MySQLDumpUtils {

    /**
     * Exporta para um arquivo os dados de uma base de dados específica.
     *
     * @param arquivo Caminho do arquivo que deve ser gerado com a
     * saída da exportação.
     * @param usuario Usuário usado para conectar na base.
     * @param senha Senha do usuário.
     * @param base Nome da base a ser exportada.
     * @param tabelas Tabelas da base especifica a serem exportadas. Caso não
     * seja expecificada nenhuma, todas as tabelas serão exportadas.
     * @throws IOException
     */
    public static void dump(
            String arquivo,
            String usuario,
            String senha,
            String base,
            String... tabelas ) throws IOException {

        // prepara o comando
        StringBuilder sbComando = new StringBuilder( "mysqldump" );

        sbComando.append( " -u " );
        sbComando.append( usuario );

        // o valor do parâmetro -p não tem espaço!
        sbComando.append( " -p" );
        sbComando.append( senha );

        sbComando.append( " " );
        sbComando.append( base );

        for ( String tabela : tabelas ) {
            sbComando.append( " " );
            sbComando.append( tabela );
        }

        // executa o comando
        Process processo = Runtime.getRuntime().exec( sbComando.toString() );

        // cria os stream gobblers, um para o stream de entrada e um para o
        // stream de erro. os gobblers vão consumir os streams do processo
        StreamGobbler sgInput = new StreamGobbler(
                processo.getInputStream(), "input", new File( arquivo ) );
        StreamGobbler sgError = new StreamGobbler(
                processo.getErrorStream(), "error" );

        // cria uma thread para cada stream gobbler e as inicia
        new Thread( sgInput ).start();
        new Thread( sgError ).start();

    }

    /**
     * Exporta para um arquivo os dados de todas as bases de dados.
     *
     * @param arquivo Caminho do arquivo que deve ser gerado com a
     * saída da exportação.
     * @param usuario Usuário usado para conectar na base.
     * @param senha Senha do usuário.
     * @throws IOException
     */
    public static void dumpAll(
            String arquivo,
            String usuario,
            String senha ) throws IOException {

        dump( arquivo, usuario, senha, "--all-databases" );

    }

    public static void main( String[] args ) throws Exception {

        // exporta as tabelas "tabelaX" e "tabelaY" da base "minha_base" para o
        // arquivo "C:/tabelaXeYMinhaBase.sql"
        dump( "C:/tabelaXeYMinhaBase.sql", "root", "root", "minha_base", "tabelaX", "tabelaY" );

        // exporta a base "minha_base" para o arquivo "C:/minhaBase.sql"
        dump( "C:/minhaBase.sql", "root", "root", "minha_base" );

        // exporta todas as bases de dados para o arquivo "C:/todasAsBases.sql"
        dumpAll( "C:/todasAsBases.sql", "root", "root" );

    }

}

/**
 * Thread para consumir os streams de processos.
 * Baseada na implementação apresentada em:
 * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1
 *
 * @author David Buzatto
 */
class StreamGobbler implements Runnable {

    private InputStream is;
    private String type;
    private FileWriter fw;

    public StreamGobbler( InputStream is, String type ) {
        this.is = is;
        this.type = type;
    }

    public StreamGobbler( InputStream is, String type, File file )
            throws IOException {
        this.is = is;
        this.type = type;
        this.fw = new FileWriter( file );
    }

    @Override
    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader( is );
            BufferedReader br = new BufferedReader( isr );
            String line = null;
            while ( ( line = br.readLine() ) != null ) {
                if ( fw != null ) {
                    fw.write( line + "\n" );
                } else {
                    System.out.println( type + ">" + line );
                }
            }
            if ( fw != null ) {
                fw.close();
            }
        } catch ( IOException ioe ) {
            ioe.printStackTrace();
        }
    }

}

Coloquei a classe StreamGobbler no mesmo arquivo para simplificar, mas seria legal vc implementá-la como uma classe pública em outro arquivo.
Se tiver alguma dúvida quanto à implementação é só falar.

Se quiser ter mais controle sobre o mysqldump, dê uma olhada na documentação dele, ai você pode inserir mais parâmetros no método dump.

[]'s

W
davidbuzatto:
Consegue sim. Acabei de montar um exemplo aqui. Dê uma olhada.

Lembre-se que você precisa adicionar o caminho do bin do MySQL na variável PATH do SO.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Classe com métodos para executar o dump do MySQL.
 * O "bin" do MySQL deve estar no PATH do SO.
 *
 * @author David Buzatto
 */
public class MySQLDumpUtils {

    /**
     * Exporta para um arquivo os dados de uma base de dados específica.
     *
     * @param arquivo Caminho do arquivo que deve ser gerado com a
     * saída da exportação.
     * @param usuario Usuário usado para conectar na base.
     * @param senha Senha do usuário.
     * @param base Nome da base a ser exportada.
     * @param tabelas Tabelas da base especifica a serem exportadas. Caso não
     * seja expecificada nenhuma, todas as tabelas serão exportadas.
     * @throws IOException
     */
    public static void dump(
            String arquivo,
            String usuario,
            String senha,
            String base,
            String... tabelas ) throws IOException {

        // prepara o comando
        StringBuilder sbComando = new StringBuilder( "mysqldump" );

        sbComando.append( " -u " );
        sbComando.append( usuario );

        // o valor do parâmetro -p não tem espaço!
        sbComando.append( " -p" );
        sbComando.append( senha );

        sbComando.append( " " );
        sbComando.append( base );

        for ( String tabela : tabelas ) {
            sbComando.append( " " );
            sbComando.append( tabela );
        }

        // executa o comando
        Process processo = Runtime.getRuntime().exec( sbComando.toString() );

        // cria os stream gobblers, um para o stream de entrada e um para o
        // stream de erro. os gobblers vão consumir os streams do processo
        StreamGobbler sgInput = new StreamGobbler(
                processo.getInputStream(), "input", new File( arquivo ) );
        StreamGobbler sgError = new StreamGobbler(
                processo.getErrorStream(), "error" );

        // cria uma thread para cada stream gobbler e as inicia
        new Thread( sgInput ).start();
        new Thread( sgError ).start();

    }

    /**
     * Exporta para um arquivo os dados de todas as bases de dados.
     *
     * @param arquivo Caminho do arquivo que deve ser gerado com a
     * saída da exportação.
     * @param usuario Usuário usado para conectar na base.
     * @param senha Senha do usuário.
     * @throws IOException
     */
    public static void dumpAll(
            String arquivo,
            String usuario,
            String senha ) throws IOException {

        dump( arquivo, usuario, senha, "--all-databases" );

    }

    public static void main( String[] args ) throws Exception {

        // exporta as tabelas "tabelaX" e "tabelaY" da base "minha_base" para o
        // arquivo "C:/tabelaXeYMinhaBase.sql"
        dump( "C:/tabelaXeYMinhaBase.sql", "root", "root", "minha_base", "tabelaX", "tabelaY" );

        // exporta a base "minha_base" para o arquivo "C:/minhaBase.sql"
        dump( "C:/minhaBase.sql", "root", "root", "minha_base" );

        // exporta todas as bases de dados para o arquivo "C:/todasAsBases.sql"
        dumpAll( "C:/todasAsBases.sql", "root", "root" );

    }

}

/**
 * Thread para consumir os streams de processos.
 * Baseada na implementação apresentada em:
 * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1
 *
 * @author David Buzatto
 */
class StreamGobbler implements Runnable {

    private InputStream is;
    private String type;
    private FileWriter fw;

    public StreamGobbler( InputStream is, String type ) {
        this.is = is;
        this.type = type;
    }

    public StreamGobbler( InputStream is, String type, File file )
            throws IOException {
        this.is = is;
        this.type = type;
        this.fw = new FileWriter( file );
    }

    @Override
    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader( is );
            BufferedReader br = new BufferedReader( isr );
            String line = null;
            while ( ( line = br.readLine() ) != null ) {
                if ( fw != null ) {
                    fw.write( line + "\n" );
                } else {
                    System.out.println( type + ">" + line );
                }
            }
            if ( fw != null ) {
                fw.close();
            }
        } catch ( IOException ioe ) {
            ioe.printStackTrace();
        }
    }

}

Coloquei a classe StreamGobbler no mesmo arquivo para simplificar, mas seria legal vc implementá-la como uma classe pública em outro arquivo.
Se tiver alguma dúvida quanto à implementação é só falar.

Se quiser ter mais controle sobre o mysqldump, dê uma olhada na documentação dele, ai você pode inserir mais parâmetros no método dump.

[]'s

Amigo, to tentando usar sua classe e estou com esse erro. O que pode ser?

java.io.IOException: Cannot run program "mysqldump": CreateProcess error=2, O sistema não pode encontrar o arquivo especificado
	at java.lang.ProcessBuilder.start(Unknown Source)
davidbuzatto

Configure o path do seu SO para enxergar os executáveis do MySQL, ou seja, o caminho para a pasta “bin” da instalação do seu servidor.
Assim o “mysqldump” poderá ser executado em qualquer diretório de seu SO.

Q

Como é a parte que faz o restore?

Criado 4 de fevereiro de 2011
Ultima resposta 21 de fev. de 2014
Respostas 6
Participantes 4