Array
(
)

PHP MYSQL

PHP
Abraão Almeida
   - 16 abr 2013

Pessoal, bom dia!
Tenho uma base de 46.000 e-mails para envio de mala direta. Recebi uma lista com mais 23.000 e-mails para incluir. Porém, antes de incluir, tenho que verificar se o e-mail está cadastrado, para só cadastrar e-mails que ainda não estou na base da mala direta.
Pergunto, tem alguma forma de fazer isso via PHP ou MySQL (SQL), para que receba toda a nova lista e só inclua os que não existem? É a primeira vez que tenho que fazer isso, e não sei como fazer.

Obrigado a todos!

Atenciosamente,

Abraão.

Bruno Betioli
   - 16 abr 2013

Coloque o campo email como UNIQUE no MySQL. Se houver algum email duplicado não irá conseguir. Depois faça um loop para inserir os emails. Se um email já estiver na base não será inserido e acusará um erro, mas, como é para apenas você inserir emails, não vejo necessidade de tratamento de erros. Informe se conseguiu.

Abraão Almeida
   - 16 abr 2013

Poxa, muito obrigado pela sua orientação.

O meu problema é que eu não estou nem sabendo como criar a função para fazer isso. Tem milhares de e-mails num .xls e preciso fazer isso.

Bruno Betioli
   - 16 abr 2013

Cara, deu um pouco de trabalho achar uma solução hehehe. Mas foi legal, aprendi algo novo.

Achei um plugin curioso chamado PHP Excel Reader. Baixe a última versão neste link http://code.google.com/p/php-excel-reader/.

Na sua pasta public, (ou www) crie uma subpasta de nome qualquer. Descompacte o arquivo baixado e jogue na subpasta o arquivo "excel_reader2.php"

Coloque na mesma subpasta um arquivo de conexão comum. O meu salvei como conexao.php e ficou assim:

#Código

<?php
$hostname_conexao = "localhost";
$database_conexao = "teste";
$username_conexao = "root";
$password_conexao = "";
$conexao = mysql_connect($hostname_conexao, $username_conexao, $password_conexao) or trigger_error(mysql_error(),E_USER_ERROR); 
mysql_select_db($database_conexao, $conexao);
?>


Depois, faça um arquivo onde iremos ler o arquivo .xls e fazer o loop para inserir emails no banco. Eu chamei de insert_email.php e ficou assim:

#Código
<?php
require_once "conexao.php";
require_once "excel_reader2.php";
error_reporting(E_ALL ^ E_NOTICE);
$data = new Spreadsheet_Excel_Reader("funcionario.xls");

for( $i=1; $i <= $data->rowcount($sheet_index=0); $i++ ){

$SQL = "INSERT INTO funcionario (email) VALUES ('".$data->val($i, 2)."')";
$Result1 = mysql_query($SQL, $conexao) ? "O email ".$data->val($i, 2)." foi inserido." : mysql_error();
echo "<br />".$Result1;
}
?>
Lembre-se de adaptar a query para o seu banco, colocar o nome do seu arquivo excel onde está funcionario.xls e substituir o número 2 de "$data->val($i, 2)" pelo número da coluna equivalente aos emails no arquivo do excel.

Ocorrerá um erro que eu nem olhei o porque dele acontecer pois ele não influencia no resultado final disso que estamos fazendo.

E eu no seu lugar controlaria o loop para inserir os emails no banco aos poucos, não todos de uma vez. Faça 500 ou 1000 de cada vez, sei lá.

Espero que ajude, informe se deu certo.

Abraão Almeida
   - 17 abr 2013

Fera, esse SCRIPT É SHOW DE BOLA!!! Funcionou redodinho!!! Não limitei a quantidade que ele deve inserir por vez, mas ele está inserido 1.058 e-mails que uma só vez. Só não faz tudo numa loop só, por causa da memória do PHP. Mas, está ótimo!

Abraão Almeida
   - 17 abr 2013

#código
<?php
require_once "conecta.php";
require_once "excel_reader2.php";
error_reporting(E_ALL ^ E_NOTICE);
$data = new Spreadsheet_Excel_Reader("lista_contato.xls");

for( $i=1; $i <= $data->rowcount($sheet_index=0); $i++ ){
if((mysql_num_rows($i) == "")){
$SQL = "INSERT INTO teste (email) VALUES ('".$data->val($i, 2)."')";
$Result1 = mysql_query($SQL, $conexao) ? "O email ".$data->val($i, 2)." foi inserido." : mysql_error();
echo "<br />".$Result1;
}
}
?>

No código acima que acrescentei a verificação

#código

if((mysql_num_rows($i) == ""))

para só inserir os e-mails que não existirem na base, porém, não funciona. Continua cadastrando os e-mails já cadastrados. Conhece alguma rotina que eu possa adicionar nesse código para que funcione?

Valeu pela ajuda!

Bruno Betioli
   - 17 abr 2013

Você colocou o campo de emails como UNIQUE como eu disse na primeira resposta? Eu coloquei aqui e testei aquele script que mandei e funcionou. Mas só vai conseguir colocar esse campo como UNIQUE se não houver emails duplicados, ou seja, vai ter que eliminar os duplicados antes. Até tem como fazer a verificação antes, mas iria consumir mais memória ainda.

Abraão Almeida
   - 17 abr 2013

Bruno Betioli, muito obrigado pela sua ajuda. Foi de grande valia.

Alterei o campo email para UNIQUE KEY e funcionou sem problemas!

Valeu pela ajuda!

Sucesso aí!

Abraão.

Bruno Betioli
   - 17 abr 2013

É nózes velho hehehe

Fico feliz em ajudar. Também aprendi com o treco.

Abrass

Bruno Betioli
   - 17 abr 2013

É nózes velho hehehe

Fico feliz em ajudar. Também aprendi com o treco.

Abrass

Abraão Almeida
   - 19 abr 2013

Bruno, tudo bem?

Aí, não tive como alterar o campo do email para UNIQUE. O problema é que esse campo além de não aceitar duplicações ele, também, remove todas as duplicações já existentes. Neste caso, se eu tivesse alterado o tipo de campo para UNIQUE. E a lista de e-mail tem uns 100.000 e-mails cadastrados que são usados por diversas listas. Com certeza, tem e-mails duplicados nessas várias listas. Então, para resolver o problema eu fiz uma adição no código PHP que você me enviou. Dá uma olhada, aí:

#codigo

for( $i=1; $i <= $data->rowcount($sheet_index=0); $i++ ){
$existe = mysql_result(mysql_query("SELECT COUNT(*) FROM teste WHERE email = '".$data->val($i, 2)."'
AND id_lista = 4"),0);
if($existe == 0){
$SQL = "INSERT INTO teste (id_lista,email) VALUES (4,'".$data->val($i, 2)."')";
$Result1 = mysql_query($SQL, $conexao) ? "O email ".$data->val($i, 2)." foi inserido." : mysql_error();
echo "<br />".$Result1;
}else{
echo "O email ".$data->val($i, 2)." já existe na base.";
}
}

#codigo

Conseguiu ver? Ele verifica se o e-mail existe e só cadastra se não existe!

Mais uma vez, muito obrigado pela sua ajuda!

Abração!!!

Bruno Betioli
   - 19 abr 2013

#Código

for($i=1; $i <= $data->rowcount($sheet_index=0); $i++ ){
$existe = mysql_fetch_assoc(mysql_query("SELECT DISTINCT EMail FROM funcionario WHERE EMail = '".$data->val($i, 8)."' LIMIT 1"));
if(empty($existe)){
$SQL = "INSERT INTO funcionario (EMail) VALUES ('".$data->val($i, 8)."')";
$Result1 = mysql_query($SQL, $conexao) ? "O email ".$data->val($i, 8)." foi inserido." : mysql_error();
echo "<br />".$Result1;
}else{
echo "<br />O email ".$data->val($i, 8)." já existe na base.";
}
}


Note que na query eu coloquei DISTINCT ao invés de COUNT. Deste modo ele para a consulta assim que encontrar o email procurado pela primeira vez. Afinal, nós apenas queremos saber se o email já está na base e não quantas vezes ele está lá.

Mas, mesmo assim, aconselho a utilizar UNIQUE. E no id_lista, utilize um valor de auto-incremento.

Se você estiver usando PHPMyAdmin, use estes comandos que estou passando como exemplo.

#Código
 ALTER IGNORE TABLE `funcionario` ADD UNIQUE INDEX(email);


Este irá adicionar UNIQUE ignorando os registros duplicados.

#Código
ALTER TABLE `funcionario` CHANGE `id` `id` VARCHAR( 10 ) NULL DEFAULT NULL 


Irá passar o campo id para VARCHAR e deixar vazio em toda a base.

#Código
ALTER TABLE `funcionario` ADD INDEX ( `id` ) 


Irá tornar o campo id em um índice, necessário para adicionar a propriedade auto-incremento.

#Código
ALTER TABLE `funcionario` CHANGE `id` `id` INT( 10 ) NOT NULL AUTO_INCREMENT 


Pronto, o campo id agora é auto-incremento.

Depois disso, pode usar aquele primeiro código que enviei. E irá enxugar sua base eliminando registros duplicados. Porém, se houver algum motivo específico para id_lista não ser auto-incremento, este último que mandei funciona, apesar de não ser muito recomendado.

Qualquer coisa grita, abrass.

OBS: esta pontuação em volta do nome da tabela é crase. Divirta-se

Abraão Almeida
   - 22 abr 2013

Pow, sempre trocando informações!!!

Aprendi mais algumas coisas agora lendo o seu post!

Abração!

Bruno Betioli
   - 22 abr 2013

hehehe, é nózes cara, também aprendi com esse negócio.

Avisa se deu certo.

Abrass

Abraão Almeida
   - 22 abr 2013

Deu certinho!!!

Redodinho!!!