Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

vinaspsy

Inserir dados verificando se o mesmo já existe

Recommended Posts

Caros,

Bom dia!

 

Desenvolvi uma página de importação de dados a partir de um arquivo .csv, nesse arquivo tem alguns dados como cpf, nome, telefone, endereço, só que é um telefone por linha fazendo com que dados como nome, cpf, endereço se repitam conforme exemplo abaixo:

00123456789;BELTRANIO DA SILVA;11;98765-432;RUA IMASTERS, 1
00123456789;BELTRANIO DA SILVA;11;2345-6789;RUA IMASTERS, 1
00123456789;BELTRANIO DA SILVA;11;2222-3333;RUA IMASTERS, 1

Pra isso fiz com que todos os dados da planilha seja importada em uma tabela temporaria, apos finalizar a inserção dos dados na tabela temporário criei um select ... insert com where not exists pra inserir o cpf e nome um uma tabela pessoas, os telefones na tabela telefones e os endereços na tabela enderço conforme exemplo abaixo:

mysqli_query($conexao, "INSERT INTO pessoas ('id', 'cpf', 'nome') 
SELECT NULL, 'cpf', 'nome' FROM temp_importacao as temp 
WHERE NOT EXISTS (SELECT cpf FROM pessoas as pes WHERE pes.cpf = temp.cpf)");

mysqli_query($conexao, "INSERT INTO telefones ('id', 'cpf', 'ddd', 'telefone') 
SELECT NULL, 'cpf', 'ddd', 'telefone' FROM temp_importacao as temp 
WHERE NOT EXISTS (SELECT cpf FROM telefones as tel WHERE tel.cpf = temp.cpf AND tel.telefone = temp.telefone)");

mysqli_query($conexao, "INSERT INTO enderecos ('id', 'cpf', 'endereco') 
SELECT NULL, 'cpf', 'endereco' FROM temp_importacao as temp 
WHERE NOT EXISTS (SELECT cpf FROM enderecos as end WHERE end.cpf = temp.cpf AND end.endereco = temp.endereco)");

Até ai tudo bem consigo inserir nas tabelas corretas sem duplicar nenhum dado, só que quando eu importo 1 milhão de cliente e depois tento importar um arquivo de apenas 1 mil clientes essa nova importação é bem demorada.

Gostaria de saber se estou fazendo da maneira correta ou se tem alguma maneira que melhore a execução, e antes que perguntem, não existe a possibilidade de alterar o layout do arquivo .csv.

 

Tabelas:

CREATE TABLE `enderecos` (
  `id` int(11) NOT NULL,
  `cpf` varchar(250) NOT NULL,
  `endereco` varchar(250) NOT NULL,
  `bairro` varchar(250) DEFAULT NULL,
  `municipio` varchar(250) DEFAULT NULL,
  `municipio_uf` varchar(999) DEFAULT NULL,
  `cep` varchar(250) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `pessoas` (
  `id` int(100) NOT NULL,
  `cpf` varchar(250) NOT NULL,
  `nome` varchar(250) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `telefones` (
  `id` int(11) NOT NULL,
  `cpf` varchar(999) NOT NULL,
  `ddd` varchar(999) NOT NULL,
  `telefone` varchar(999) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `temp_importacao` (
  `id` int(11) NOT NULL,
  `cpf` varchar(999) NOT NULL,
  `nome` varchar(9999) NOT NULL,
  `ddd` varchar(999) NOT NULL,
  `telefone` varchar(999) NOT NULL,
  `status` varchar(999) NOT NULL,
  `cep` varchar(999) NOT NULL,
  `endereco` varchar(9999) NOT NULL,
  `bairro` varchar(9999) NOT NULL,
  `cidade` varchar(9999) NOT NULL,
  `estado` varchar(999) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

 

importar-mailing.php

<?php
    session_start();
    set_time_limit(0);
    include'../includes/dbconfig.php';
    include'../includes/funcoes.php';
    header ('Content-type: text/html; charset=ISO-8859-1', true);
    $usar_utf8_decode = 'nao';
    
    if (!isset($_SESSION["login"])){
        echo "<script>location.href='../login/'</script>";
    }else{
        if( isset($_POST['importar']) ){
            mysqli_query($conexao, "TRUNCATE `temp_importacao`");
            for($i=0; $i<count($_FILES['arquivos-importar']['name']); $i++) {
                $temporario = $_FILES['arquivos-importar']['tmp_name'][$i];
                $novoCaminho = "../uploads/" . $_FILES['arquivos-importar']['name'][$i];
                if($temporario != ""){
                    move_uploaded_file($temporario, $novoCaminho);
                }
                
                    $data_imp = date( 'Y-m-d H:i:s' );
                    
                    $abraArq = fopen($novoCaminho, "r");
                    if ($abraArq){
                        $c=0;
                        while ($valores = fgetcsv ($abraArq, 0, ";")) {
                        $cpf            = mysqli_real_escape_string($conexao, $valores[0]);
                        $nome            = mysqli_real_escape_string($conexao, $valores[1]);
                        $ddd            = mysqli_real_escape_string($conexao, $valores[2]);
                        $telefone        = mysqli_real_escape_string($conexao, $valores[3]);
                        $status            = mysqli_real_escape_string($conexao, $valores[4]);
                        $cep            = mysqli_real_escape_string($conexao, $valores[5]);
                        $endereco        = mysqli_real_escape_string($conexao, $valores[6]);
                        $bairro            = mysqli_real_escape_string($conexao, $valores[7]);
                        $cidade            = mysqli_real_escape_string($conexao, $valores[8]);
                        $estado            = mysqli_real_escape_string($conexao, $valores[9]);
                            
                        $c++;
                            if($c > 1){
                                mysqli_query($conexao, "INSERT INTO `temp_importacao`(`id`, `cpf`, `nome`, `ddd`, `telefone`, `status`, `cep`, `endereco`, `bairro`, `cidade`, `estado`) VALUES (NULL, '".$cpf."', '".$nome."', '".$ddd."', '".$telefone."', '".$status."', '".$cep."', '".$endereco."', '".$bairro."', '".$cidade."', '".$estado."')") or die (mysqli_error($conexao));
                            }
                        }
                    }
                    fclose($abraArq);
                   
                         
                    unlink($novoCaminho);
                    mysqli_query($conexao, "TRUNCATE `temp_importacao`");
            }
            
            mysqli_query($conexao, "INSERT INTO `telefones` (`id`, `cpf`, `ddd`, `telefone`) SELECT NULL, `cpf`, `ddd`, `telefone` FROM `temp_importacao` `temp` WHERE NOT EXISTS (SELECT `cpf`, `telefone` FROM `telefones` `fone` WHERE `temp`.`cpf` = `fone`.`cpf` AND `temp`.`telefone` = `fone`.`telefone`)") or die (mysqli_error($conexao));
                    
            mysqli_query($conexao, "INSERT INTO `enderecos` (`id`, `cpf`, `endereco`, `bairro`, `municipio`, `municipio_uf`, `cep`) SELECT DISTINCT NULL, `cpf`, `endereco`, `bairro`, `cidade`, `estado`, `cep` FROM `temp_importacao` `temp` WHERE NOT EXISTS (SELECT `cpf`, `cep` FROM `enderecos` `end` WHERE `temp`.`cpf` = `end`.`cpf` AND `temp`.`cep` = `end`.`cep`)") or die (mysqli_error($conexao));
            
            mysqli_query($conexao, "INSERT INTO `pessoas` (`id`, `cpf`, `nome`) SELECT DISTINCT NULL, `cpf`, `nome` FROM `temp_importacao` `temp` WHERE NOT EXISTS (SELECT `cpf` FROM `pessoas` `pes` WHERE `temp`.`cpf` = `pes`.`cpf`)") or die (mysqli_error($conexao));
            
        }else{
?>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1">
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Projeto Europa » TeleVenda</title>
    <link href="../includes/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="../includes/bootstrap/css/bootstrap-theme.css" rel="stylesheet">
    <link href="../includes/jquery-ui/css/smoothness/jquery-ui-1.10.4.min.css" rel="stylesheet">
    <link rel="shortcut icon" href="../includes/icons/fav.ico" type="image/x-icon"/>
    
    <script src="../includes/bootstrap/js/bootstrap.min.js"></script>
    <script type="../includes/js/jsapi"></script>
    <script src="../includes/bootstrap/js/jquery.min.js"></script>
    <script src="../includes/jquery-ui/js/jquery-ui-1.10.4.js"></script>
    <script src="../includes/bootstrap/js/bootstrap.min.js"></script>
    <style>
    body {
        padding-top: 60px; 
        background-color: #f5f5f5;
    }
    .ui-datepicker{
        font-size:9pt;
    }
    table.ui-datepicker-calendar td.ui-datepicker-week-end:nth-child(1) a{
        background: #fd6e6e;
        color: white;
    }
    </style>
  </head>
  <body role="document" style="min-width:1010px;">
    <?php echo menuPrincipal("importacao-exportacao", "importar-mailing"); ?>
        <div class="container-fluid theme-showcase" role="main">
            <div class="panel panel-default" style="min-width:450px;">
                <div class="panel-body">
                    <div class="row">
                        <div class="col-md-12">
                            <div class="pull-right">
                                <img width="150" src="../includes/icons/logo1.png" />
                            </div>
                                <h2>IMPORTAÇÃO</h2>
                                <hr></hr>
                            <div style="clear:both;">
                            </div>
                        </div>
                    </div>
                    <form action="" method="POST" enctype="multipart/form-data" class="form-importar">
                        <input type="hidden" name="importar" value="" />
                        <div class="row">
                            <div class="col-md-3">
                            </div>
                            <div class="col-md-12">
                                <span>Selecione um arquivo no formato .csv com a lista de clientes para serem importados no sistema.</span><br /><br />
                                <center>
                                <input type="file" name="arquivos-importar[]" id="arquivos-importar" class="arquivos-importar" style="display: none;" multiple />
                                <button type="button" class="btn btn-default btn-lg slt-arquivos-importar" onclick="document.getElementById('arquivos-importar').click();" ><span class="glyphicon glyphicon-open" aria-hidden="true"></span> Selecionar arquivos...</button>
                                <button type="submit" class="btn btn-info btn-lg enviar-arquivos-importar active disabled"><span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> Enviar</button>
                                </center>
                            </div>
                        </div>
                        <br />
                        <div class="row">
                            <div class="col-md-3">
                            </div>
                            <div class="col-md-6">
                                <div class="progress progress-arquivos-importar" style="margin-top:12px;display:none;">
                                    <div class="progress-bar progress-bar-success progresso-arquivos-importar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
                                    </div>
                                    <br />
                                </div>
                                <b class="arq-selecionados-arquivos-importar" style="display:none;"></b>
                                <table class="table table-striped table-bordered selecionados-arquivos-importar" cellspacing="0" cellpadding="0" style="margin-top: 5px;"></table>
                                <center><div class="retorno-arquivos-importar"></div></center>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
        
        <script>
            function progress_arquivos_importar(e){
                if(e.lengthComputable){
                    var max = e.total;
                    var current = e.loaded;
                    var Percentage = (current * 100)/max;
                        $( ".progress-arquivos-importar" ).show();
                        $( ".progresso-arquivos-importar" ).css( 'width', Percentage + '%' );
                        $( ".progresso-arquivos-importar" ).html( Math.round(Percentage) + '%' );
                    if(Percentage >= 100){
                        $( '.enviar-arquivos-importar' ).html( '<span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> Importando...' ).addClass( 'active disabled' );
                    }
                }  
            }
            
            $( 'body' ).on('change', '.arquivos-importar', function(e){
                $( '.arq-selecionados-arquivos-importar' ).hide();
                $( '.selecionados-arquivos-importar, .retorno-arquivos-importar' ).html( '' );
                $( '.enviar-arquivos-importar' ).addClass( 'active disabled' );
                for (var i = 0; i < this.files.length; i++){
                    if( this.files[i].size <= 1024 ){
                        var tamanho = this.files[i].size + ' bytes';
                    }else if( this.files[i].size < 1048576 ){
                        var tamanho = Math.round(this.files[i].size/1024) + ' kb';
                    }else if( this.files[i].size < 1073741824 ){
                        var tamanho = Math.round(this.files[i].size/1048576) + ' mb';
                    }else if( this.files[i].size < 1099511627776 ){
                        var tamanho = Math.round(this.files[i].size/1073741824) + ' gb';
                    }else{
                        var tamanho = this.files[i].size + ' bytes';
                    }
                    if( this.files[i].name.indexOf( '.csv' ) != -1 ){
                        $( '.selecionados-arquivos-importar' ).append( '<tr><td><span class="text-success"><b>Nome:</b> ' + this.files[i].name + '</span></td><td><span class="text-success"><b>Tamanho:</b> ' + tamanho + '</span></td></tr>').show();
                    }else{
                        $( '.selecionados-arquivos-importar' ).append( '<tr><td><span class="text-danger"><b>Nome:</b> ' + this.files[i].name + '<b style="margin-left:10px;float:right;">(arquivo inválido)</b></span></td><td><span class="text-danger"><b>Tamanho:</b> ' + tamanho + '</span></td></tr>').show();
                    }
                    $( '.enviar-arquivos-importar' ).removeClass( 'active disabled' );
                    if( this.files.length > 1 ){
                        $( '.arq-selecionados-arquivos-importar' ).html( this.files.length + ' arquivos selecionados' ).show();
                    }else{
                        $( '.arq-selecionados-arquivos-importar' ).html( this.files.length + ' arquivo selecionado' ).show();
                    }
                }
            });
            
            $( 'body' ).on('submit', '.form-importar', function(e){
                e.preventDefault();
                arquivoInvalido = false;
                $( '.arquivos-importar' ).each(function(){
                    if( $( '.arquivos-importar' ).val().split('.').pop() != "csv" ){
                        arquivoInvalido = true;
                    }
                });
                
                if( !$( '.arquivos-importar' ).val() ){
                    $( '.modal-erro' ).modal({
                        keyboard: false,
                        backdrop: 'static'
                    });
                    $( '.modal-erro-body' ).html( '<center><label class="text-danger">Você não selecionou o arquivo!</label></center>' );
                }else if( arquivoInvalido == true ){
                    $( '.modal-erro' ).modal({
                        keyboard: false,
                        backdrop: 'static'
                    });
                    $( '.modal-erro-body' ).html( '<center><label class="text-danger">Você deve selecionar apenas arquivos .csv</label></center>' );
                }else{
                    $( '.enviar-arquivos-importar' ).html( 'Enviando arquivo...' ).addClass( 'active disabled' );
                    $( '.slt-arquivos-importar' ).addClass( 'active disabled' );
                    var formData = new FormData(this);
                    $.ajax({
                        type:'POST',
                        url: "importar-mailing.php",
                        data:formData,
                        xhr: function() {
                            var myXhr = $.ajaxSettings.xhr();
                            if(myXhr.upload){
                                myXhr.upload.addEventListener('progress',progress_arquivos_importar, false);
                            }
                            return myXhr;
                        },
                        cache:false,
                        contentType: false,
                        processData: false,
                        success:function(data){
                            $( ".progress-arquivos-importar" ).hide();
                            $( '.enviar-arquivos-importar' ).html( '<span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> Enviar' ).removeClass( 'active disabled' );
                            $( '.slt-arquivos-importar' ).removeClass( 'active disabled' );
                            $( '.arq-selecionados-arquivos-importar, .selecionados-arquivos-importar' ).html( '' ).hide();
                            $( '.arquivos-importar' ).val( '' );
                            $( '.retorno-arquivos-importar' ).html( '<h3><label class="text-success">Arquivo(s) enviado(s) com sucesso.</label></h3>' + data );
                        },
                        error: function(data){
                            $( '.modal-erro' ).modal({
                                keyboard: false,
                                backdrop: 'static'
                            });
                            $( '.modal-erro-body' ).html( '<center><label class="text-danger">Ocorreu um erro: ' + data + '</label></center>' );
                        }
                    });
                    e.preventDefault();
                }
            });
        </script>
        
  </body>
</html>
<?php
        }
    }
?>

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Há uma sério problema de modelagem e desperdício de processos.

 

Uma Pessoa contém um CPF, mas endereços e telefones não.

 

O que tem de conter nas tabelas endereços e telefones é uma chave estrangeira  da tabela pessoas que faça referencia ao ID de Cadastro desta Pessoa, desta forma você mantém toda a integridade do banco de dados, podendo usar até DELETE CASCATE se bem configurada. 

 

Para evitar duplicação no Banco, você pode criar restrições do tipo UNIQUE e tratar o erro. Dispensando esta tabela temporária, que de temporária só no nome.

 

Veja como criar tabelas temporárias em PT_BR

 

Veja também

https://pt.wikipedia.org/wiki/Normalização_de_dados

 

Muita gente não gosta do veredito, prefere remédios, mas o que tenho a falar do código acima é: Refaça!:smile:

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, pra que esse monte de varchar(999) ?
 

Você consegue saber com exatidão a quantidade maxima de caracteres de um campo cpf, ddd, telefone, status, estado, cidade, cep especifique a quantidade de bytes de acordo com a necessidade
 

Utilize o tipo de dado adequado, não use varchar em tudo, veja a tabela abaixo:
http://www.rcoli.com.br/2012/08/tipos-de-campos-no-mysql-saiba-como-escolher-o-tipo-correto/
 

Outra coisa que vai melhorar consideravelmente a velocidade, é a indexação! Crie indices de acordo com os campos que você ira utilizar no filtro de suas consultas, caso ainda não tenha feito isso, faça, a diferença sera gritante!
 

Outra dica, delete os indices antes da coleta e recrie apos finalizar, isso pq os indices vão acelerar as consultas, mas no caso de inserção em massa, vão atrapalhar.
 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Williams e EdCesar,

 

Obrigado pela ajuda, vou refazer todo o código conforme as dicas que vocês me deram  e assim que eu tiver finalizado dou um feedback.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por ILR master
      Fala galera.
      Espero que todos estejam bem.
      Seguinte: Tenho um arquivo xml onde alguns campos estão com : (dois pontos), como o exemplo abaixo:
       
      <item>
      <title>
      d sa dsad sad sadasdas
      </title>
      <link>
      dsadas dsa sad asd as dsada
      </link>
      <pubDate>sadasdasdsa as</pubDate>
      <dc:creator>
      d sad sad sa ad as das
      </dc:creator>
      </item>
       
      Meu código:
       
      $link = "noticias.xml"; 
      $xml = simplexml_load_file($link); 
      foreach($xml -> channel as $ite) {     
           $titulo = $ite -> item->title;
           $urltitulo = $ite -> item->link;
           print $urltitulo = $ite -> item->dc:creator;
      } //fim do foreach
      ?>
       
      Esse campo dc:creator eu não consigo ler. Como faço?
       
      Agradeço quem puder me ajudar.
       
      Abs
       
       
    • Por First
      Olá a todos!
       
      Eu estou criando um sistema do zero mas estou encontnrando algumas dificuldades e não estou sabendo resolver, então vim recorrer ajuda de vocês.
      Aqui está todo o meu código: https://github.com/PauloJagata/aprendizado/
       
      Eu fiz um sistema de rotas mas só mostra o conteúdo da '/' não sei porque, quando eu tento acessar o register nada muda.
      E eu também quero que se não estiver liberado na rota mostra o erro de 404, mas quando eu tento acessar um link inválido, nada acontece.
      Alguém pode me ajudar com isso? E se tiver algumas sugestão para melhoria do código também estou aceitando.
       
       
      Desde já, obrigado.
    • Por landerbadi
      Olá pessoal, boa tarde
       
      Tenho uma tabela chamada "produtos" com os seguintes campos (id, produto) e outra tabela chamada "itens" com os seguintes campos (id, prod_01, prod_02, prod_03, prod_04).
       
      Na tabela produtos eu tenho cadastrado os seguintes produtos: laranja, maçã, uva, goiaba, arroz, feijão, macarrão, etc.
       
      Na tabela itens eu tenho cadastrado os itens da seguinte maneira:
       
      1, laranja, uva, arroz, feijão;
      2, maçã, macarrão, goiaba, uva;
      3, arroz, feijão, maçã, azeite
       
      Meu problema é o seguinte: 
      Eu escolho um produto da tabela "produtos", por exemplo "uva".  Preciso fazer uma consulta na tabela "itens" para ser listado todos os registros que contenham o produto "uva" e que todos os demais produtos estejam cadastrados na tabela "produtos".
       
      No exemplo acima seria listado apenas dois registros, pois o terceiro registro não contém o produto "uva". 
       
      Alguém pode me ajudar? Pois estou quebrando a cabeça a vários dias e não consigo achar uma solução.
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.