Problemas ao ler arquivo txt e enviar para SQL Server

Bom dia meu nome é Rafael e gostaria de saber se poderiam me ajudar, estou tentando ler um arquivo txt no netbeans e enviar as informações para o banco de dados SQL Server 2014, mas estou tendo problemas.

Segue informações do txt.

|C100|0|1|04400552000148|55|00|2|176676|13131104400552000148550020001766761001766766|07112013|03012014|42250|1|0||42250|0|0|0|0|0|0|0|0|0|274,63|1267,5|||

|C100|0|1|04400552000148|55|00|2|176677|13131104400552000148550020001766771001766771|07112013|03012014|42250|1|0||42250|0|0|0|0|0|0|0|0|0|274,63|1267,5|||

Meu código está conseguindo filtrar as informações, mas na hora de passar para o banco os 2 últimos valores nulos está dando problemas.

Segue codificação:

public void Inserir() throws SQLException {
File dir = new File(“C:\Users\rafael.drumond\Desktop\BDO Java projeto”);

    File arq = new File(dir, "teste.txt");

    try {
        Statement stmt = con.createStatement();
        //Indicars o arquivo que será lido
        FileReader fileReader = new FileReader(arq);

        //Criar o objeto bufferReader que nos
        // oferece o método de leitura readLine()
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        //String que irá receber cada linha do arquivo
        String linha = "";

        //Fazer um loop linha a linha no arquivo,
        // enquanto ele seja diferente de null.
        //O método readLine() devolve a linha na
        // posicao do loop para a variavel linha.
        while ((linha = bufferedReader.readLine()) != null) {
            //imprimimosr a linha
            //System.out.println(linha);

            String[] str = linha.split("\\|");//Aqui
            for (int i = 1; i < str.length; i++) {
                if (str[1].equals("C100")) {

                    System.out.println("str[" + i + "] :" + str[i]);
                }

            }

            if (str[1].equals("C100")) {
                // Prepare a statement to insert a record  
                String sql = "insert into C100 (REG, IND_OPER, IND_EMIT, COD_PART, COD_MOD, COD_SIT, SER, NUM_DOC, CHV_NFE, DT_DOC,"
                        + " DT_E_S, VL_DOC, IND_PGTO, VL_DESC, VL_ABAT_NT, VL_MERC, IND_FRT, VL_FRT, VL_SEG, VL_OUT_DA,"
                        + " VL_BC_ICMS, VL_ICMS, VL_BC_ICMS_ST, VL_ICMS_ST, VL_IPI, VL_PIS, VL_COFINS, VL_PIS_ST,VL_COFINS_ST) values ('"
                        + str[1] + "','" + str[2] + "','" + str[3] + "','" + str[4] + "','" + str[5] + "','" + str[6] + "','" + str[7] + "','"
                        + str[8] + "','" + str[9] + "','" + str[10] + "','" + str[11] + "','" + str[12] + "','" + str[13] + "','" + str[14] + "','" + str[15] + "','" + str[16]
                        + "','" + str[17] + "','" + str[18] + "','" + str[19] + "','" + str[20] + "','" + str[21] + "','" + str[22] + "','" + str[23]
                        + "','" + str[24] + "','" + str[25] + "','" + str[26] + "','" + str[27] + "','" + str[28] + "','" + str[29] + "');";

                //Execute the insert statement  
                stmt.executeUpdate(sql);
            }
        }

        //liberar o fluxo dos objetos ou fechar o arquivo
        fileReader.close();
        bufferedReader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Poderiam me ajudar?

Desde já muito obrigado.

@rafael1501 o problema é salvar um valor null ou tratar os valores que não vêm no arquivo txt? Eu acredito que vc pode tratar os valores null e caso seja nulo, informar um valor default. No seu caso como é valor de pis e cofins, talvez se for null, vc poderia informar 0.
Além disso tome muito cuidado com seu insert pois não esta tratando nada, qualquer valor inclusive de sql injection esta sendo passado direto.

1 curtida

Rodrigo, obrigado pela ajuda, sou novo em java me perdoe se estou me equivocando em algo.

Quando eu tiro os 2 últimos valores da inserção (VL_PIS_ST, VL_CONFINS_ST, str[28] e str[29]) consigo enviar as informações normalmente para o banco mas quando tento inserir com eles está aparecendo o erro “Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 28”.

Noto que quando eu ponho um número qualquer em VL_COFINS_ST ele consegue enviar para o banco normalmente então acho que não é um problema de leitura das linhas.

Em relação ao tratamento no insert irei providenciar a correção muito obrigado.

Quando você faz o split e não há nada entre os separadores (pipes, no seu caso), essa posição não é gerada no array final. Parece que você imagina que ela deveria vir em branco, mas não é assim que funciona. Veja:

String str = "|C100|0|1|04400552000148|55|00|2|176676|13131104400552000148550020001766761001766766|07112013|03012014|42250|1|0||42250|0|0|0|0|0|0|0|0|0|274,63|1267,5|||";

String[] dados = str.split("\\|");
    	
for (int i = 1; i < dados.length; i++) {
  System.out.println("dados[" + i + "] :" + dados[i]);
}

Se você executar este código, verá que dados.length é 27, não 29. Se você tenta acessar posições maiores que 27, obtém ArrayIndexOutOfBoundsException.

Uma solução simples seria adicionar ifs para verificar se as duas últimas posições existem. Algo como:

if (dados.length == 29){
String sql = "insert into C100 (REG, IND_OPER, IND_EMIT, COD_PART, COD_MOD, COD_SIT, SER, NUM_DOC, CHV_NFE, DT_DOC,"
                    + " DT_E_S, VL_DOC, IND_PGTO, VL_DESC, VL_ABAT_NT, VL_MERC, IND_FRT, VL_FRT, VL_SEG, VL_OUT_DA,"
                    + " VL_BC_ICMS, VL_ICMS, VL_BC_ICMS_ST, VL_ICMS_ST, VL_IPI, VL_PIS, VL_COFINS, VL_PIS_ST,VL_COFINS_ST) values ('"
                    + str[1] + "','" + str[2] + "','" + str[3] + "','" + str[4] + "','" + str[5] + "','" + str[6] + "','" + str[7] + "','"
                    + str[8] + "','" + str[9] + "','" + str[10] + "','" + str[11] + "','" + str[12] + "','" + str[13] + "','" + str[14] + "','" + str[15] + "','" + str[16]
                    + "','" + str[17] + "','" + str[18] + "','" + str[19] + "','" + str[20] + "','" + str[21] + "','" + str[22] + "','" + str[23]
                    + "','" + str[24] + "','" + str[25] + "','" + str[26] + "','" + str[27] + "','" + str[28] + "','" + str[29] + "');";
}else if (dados.length == 28){
String sql = "insert into C100 (REG, IND_OPER, IND_EMIT, COD_PART, COD_MOD, COD_SIT, SER, NUM_DOC, CHV_NFE, DT_DOC,"
                    + " DT_E_S, VL_DOC, IND_PGTO, VL_DESC, VL_ABAT_NT, VL_MERC, IND_FRT, VL_FRT, VL_SEG, VL_OUT_DA,"
                    + " VL_BC_ICMS, VL_ICMS, VL_BC_ICMS_ST, VL_ICMS_ST, VL_IPI, VL_PIS, VL_COFINS, VL_PIS_ST) values ('"
                    + str[1] + "','" + str[2] + "','" + str[3] + "','" + str[4] + "','" + str[5] + "','" + str[6] + "','" + str[7] + "','"
                    + str[8] + "','" + str[9] + "','" + str[10] + "','" + str[11] + "','" + str[12] + "','" + str[13] + "','" + str[14] + "','" + str[15] + "','" + str[16]
                    + "','" + str[17] + "','" + str[18] + "','" + str[19] + "','" + str[20] + "','" + str[21] + "','" + str[22] + "','" + str[23]
                    + "','" + str[24] + "','" + str[25] + "','" + str[26] + "','" + str[27] + "','" + str[28] + "');";
}else if (dados.length == 27){
String sql = "insert into C100 (REG, IND_OPER, IND_EMIT, COD_PART, COD_MOD, COD_SIT, SER, NUM_DOC, CHV_NFE, DT_DOC,"
                    + " DT_E_S, VL_DOC, IND_PGTO, VL_DESC, VL_ABAT_NT, VL_MERC, IND_FRT, VL_FRT, VL_SEG, VL_OUT_DA,"
                    + " VL_BC_ICMS, VL_ICMS, VL_BC_ICMS_ST, VL_ICMS_ST, VL_IPI, VL_PIS, VL_COFINS) values ('"
                    + str[1] + "','" + str[2] + "','" + str[3] + "','" + str[4] + "','" + str[5] + "','" + str[6] + "','" + str[7] + "','"
                    + str[8] + "','" + str[9] + "','" + str[10] + "','" + str[11] + "','" + str[12] + "','" + str[13] + "','" + str[14] + "','" + str[15] + "','" + str[16]
                    + "','" + str[17] + "','" + str[18] + "','" + str[19] + "','" + str[20] + "','" + str[21] + "','" + str[22] + "','" + str[23]
                    + "','" + str[24] + "','" + str[25] + "','" + str[26] + "','" + str[27] + "');";
}

stmt.executeUpdate(sql);

Obviamente, é uma solução bem confusa e com muita redundância. O ideal seria você usar um preparedStatement com parâmetros para cada campo, e preencher com null ou deixar em branco os campos que não estiverem no array.

Abraço.

2 curtidas

Exatamente como o @TerraSkilll falou… com um preparestatement isso seria bem mais fácil de ser tratado e com bem menos furos de segurança… seria até legal criar uma entidade com seus atributos do arquivo para organizar melhor :smiley:

Obrigado pessoal vou tentar inserir com preparestatement