[RESOLVIDO] Ler arquivo e gravar em diferentes tabelas

Tenho um projeto para importar txt para o banco, só que preciso importar para duas tabelas dependendo da primeira coluna do txt($REG), pensei em fazer deste jeito, mas não executa.

<?php
session_start();
ob_start();
//Incluir a conexao com BD
include_once("conexao/conexao.php");

//Receber os dados do formulário
//$arquivo = $_FILES['arquivo'];
//var_dump($arquivo);
$arquivo_tmp = $_FILES['arquivo']['tmp_name'];
    
//ler todo o arquivo para um array
$dados = file($arquivo_tmp);
//var_dump($dados);

foreach($dados as $linha){
        $linha = trim($linha);
	$valor = explode('|', $linha);
	//var_dump($valor);
	
	$REG = $valor[1];
        
        switch ( $REG ) {
        case 1: 
        $COD_ITEM = $valor[2];
        $UNID = $valor[3];
        $cod1 = "INSERT INTO r1 (REG, COD_ITEM, UNID) VALUES ('$REG','$COD_ITEM','$UNID')";
        continue; 

        case 2:
        $COD_ITEM = $valor[2];
        $UNID = $valor[3];
        $cod1 = "INSERT INTO r1 (REG, COD_ITEM, UNID) VALUES ('$REG','$COD_ITEM','$UNID')";
        break;

Acho que você já pode considerar importar o arquivo em uma tabela “temporária” (load file mysql), e a partir dela distribuir para outras tabelas usando insert com select…

O link te mostra um recurso do mysql de importar arquivo diretamente e o melhor, possui um “identificador de coluna” (FIELDS TERMINATED BY ‘|’) olha que legal!? Assim você não precisa ficar “destrinchando” o arquivo pelo php e nem precisa de for para isso…

Depois de inserido o arquivo direto numa tabela, você pode separar as linhas +/- assim:

INSERT INTO r1 (REG, COD_ITEM, UNID) 
SELECT REGT, COD_ITEMT, UNIDT FROM temp WHERE REGT = 1;

INSERT INTO r2 (REG, COD_ITEM, UNID) 
SELECT REGT, COD_ITEMT, UNIDT FROM temp WHERE REGT = 2;

Viu que “loko o bagui mano”!? Com três queries você mata o que precisa e ainda o php fica livre de muita regra…

Você só precisa ensinar o MySQL sobre as “colunas das pontas” lembra?

Pesquise mais a respeito é um recurso que vai te ajudar muito, boa sorte!

Fiz assim:

<?php
      include_once("conexao/conexao.php");`
    //Receber os dados do formulário
                $arquivo = $_FILES['arquivo'];
               
                  $arqload = "LOAD LOCAL DATA INFILE '$arquivo' INTO TABLE 
                temp FIELDS TERMINATED BY '|' LINES STARTING BY '|'  LINES T;ERMINATED BY '|'  ";

           $result = "INSERT INTO temp (REG, COD_ITEM, UNID, COD_USER, IND) VALUES ('$REG','$COD_ITEM','$UNID','$COD_USER','$IND')";

Só que tenho um problema cada REG vai ter quantidade de colunas diferentes, tipo da tabela r1 vou ter 3 colunas de dados e r2 quatro

Estruture sua tabela temp para compor o maior numero de colunas e no select de cada uma é só filtrar os campos ué! :joy:

Eu só não me recordo se você precisa deixar a ordem das colunas adequadas, por exemplo se na reg2 tem quatro colunas, a coluna que difere de reg1 deveria estar por ultimo…

Dica: não precisa ficar removendo sua resposta, basta editar…

Mas os dados não vão invadir os outros de outras colunas?

Como te falei, vc precisa estabelecer uma ordem, seja no import do arquivo ou no select para transferir os dados por exemplo:

Se no reg1 vc tem

REG|COD_ITEM|UNID|COD_USER

E no reg2

REG|COD_ITEM|UNID|COD_USER|IND

A temp terá que ter o maior numero de colunas ou seja:

REG|COD_ITEM|UNID|COD_USER|IND

Ou melhor ainda:

REG | COL1 | COL2 | COL3 | COL4

O que estou tentando te passar é que a temp não precisa ter os nomes iguais as colunas “originais”, ela pode ter qualquer coisa, o que vale é a quantidade de colunas que terá para compor qualquer estrutura, na saida você quem vai determinar a orderm dos campos:

INSERT INTO reg2 (REG, COD_ITEM, UNID, COD_USER, IND)
SELECT REG, COL2, COL4, COL1, COL3 FROM temp WHERE REG = 2;

Percebeu? é você quem cria a regra de transferência, afinal é vc quem sabe a regra de negócio do seu sistema, boa sorte :wink:

Entendi, agora só falta eu arrumar a parte do meu código, pois está dando erro

Tem mensagem?

Vc já consegue salvar o arquivo na temp?

@rodevops A página retorna em branco

$arqload = "LOAD LOCAL DATA INFILE 'arquivo.txt' INTO TABLE temp FIELDS TERMINATED BY '|'"
        . "(@REG, @COL1, @COL2, @COL3, @COL4, @COL5, @COL6, @COL7, @COL8, @COL9, @COL10, @COL11, @COL12)"
        . "REG = NULLIF(@REG, 'null'),
            COL1  = NULLIF(@COL1, 'null'),
            COL2 = NULLIF(@COL2, 'null'),
            COL3 = NULLIF(@COL3, 'null'),
            COL4 = NULLIF(@COL4, 'null')
            COL5 = NULLIF(@COL5, 'null')
            COL6 = NULLIF(@COL6, 'null')
            COL7 = NULLIF(@COL7, 'null')
            COL8 = NULLIF(@COL8, 'null')
            COL9 = NULLIF(@COL9, 'null')
            COL10 = NULLIF(@COL10, 'null')
            COL11 = NULLIF(@COL11, 'null')
            COL12 = NULLIF(@COL12, 'null')";

Não entendi porque vc precisa dessa query desse tamanho, não seria só isso para importar?

$arqload = "LOAD LOCAL DATA INFILE 'arquivo.txt' INTO TABLE temp FIELDS TERMINATED BY '|'";

Lembre-se que o processo na teoria seria feito em 3 sql’s, um para importar, outro para transferir para tabela1 e outro para tabela 2…

Entendi agora mano, muuuuuuuuito obrigado :cupid:

1 curtida

Ufa, missão comprida! :joy:

Agora que vc pegou o esquema, pode melhorar ainda mais no futuro, deixando as rotinas do banco dentro de uma procedure e fazer o php passar para ela apenas o nome do arquivo ó que loko?

Vai brincando que uma hora sai, sucesso irmão! :v:

Só mais uma pergunta, não querendo abusar mas já abusando, o meu jeito de chamar o arquivo está correta? no formulário o input está da seguinte maneira: <input type="file" name="arquivo">

Ai vc precisa pesquisar sobre $_FILES e mover o arquivo enviado para uma pasta que você tenha controle para depois informar o nome completo do arquivo (ex: C:/pasta/arquivo.txt) para o banco importar (detalhe: o banco precisa estar no mesmo servidor que o php para acessar a pasta…)

Pesquise também sobre a função move_uploaded_file

Agora é contigo, boa sorte!