Problemas para fazer upload de arquivo CSV *** RESOLVIDO ***

PessoALL,

Dá uma ajuda ai… não sei o que há de errado no código abaixo… podem me ajudar a ver o que é? Está dando erro como se o array $CAMPOS não existisse… acho que é cansaço mesmo…

// Pegando o arquivo com caminho
$caminho = $this->Ini->path_doc;
$arq = $caminho.'/'.{arquivo};

// Processando a leitura
$fp = fopen($arq,'r');

// Pegando a primeira linha (cabeçalho)
$linha = fgets($fp);

// Pegando o caracter separador na coluna 5
$caracter = substr($linha,5,1);

// Processando arquivo
while (!feof($fp))
{
     $linha = fgets($fp);
     $campos = explode($caracter,$linha);
     $insert_fields = array("chaveagente     = '$campos[0]'",
                            "nome_loj        = '$campos[2]'",
                            "nome_func       = '$campos[3]'",
                            "dat_nascimento  = '".substr($campos[5],6,4).'-'.substr($campos[5],3,2).'-'.str_pad(substr($campos[5],0,2),2,'0',STR_PAD_LEFT)."'",
                            "celular         = '$campos[6]'",
                            "fone_comercial  = '$campos[7]'",
                            "fone_residencia = '$campos[8]'",
                            "cpffunc         = '".preg_replace('#[^0-9]#', '', $campos[9])."'",
                            "situacao        = ".($campos[15]=='ATIVO' ? 0 : 1),
                            "identidade      = '$campos[17]'",
                            "uf_emissor      = '$campos[18]'",
                            "endereco        = '$campos[19]'",
                            "bairro          = '$campos[20]'",
                            "cidade          = '$campos[21]'",
                            "cep             = '$campos[22]'",
                            "sexo            = '$campos[26]'",
                            "tip_colab       = '$campos[4]'",
                            "cod_funcao      = 1");
}
$insert_table  = 'tab_func';

// Inserir registros
$insert_sql = 'INSERT ' . $insert_table
            . ' SET '   . implode(', ', $insert_fields);
sc_exec_sql($insert_sql);

fclose($fp);

O erro que dá é:

Undefined index: 2
Undefined index: 3
Undefined offset: 5
Undefined offset: 5
Undefined offset: 5
Undefined index: 6
Undefined index: 7
Undefined index: 8
Undefined offset: 9
Undefined offset: 15
Undefined index: 17
Undefined index: 18
Undefined index: 19
Undefined index: 20
Undefined index: 21
Undefined index: 22
Undefined index: 26
Undefined index: 4
Erro ao acessar o banco de dados
Incorrect date value: '--00' for column 'DAT_NASCIMENTO' at row 1
{SC_DB_ERROR_INI}View SQL{SC_DB_ERROR_MID}INSERT tab_func SET chaveagente = '', nome_loj = '', nome_func = '', dat_nascimento = '--00', celular = '', fone_comercial = '', fone_residencia = '', cpffunc = '', situacao = 1, identidade = '', uf_emissor = '', endereco = '', bairro = '', cidade = '', cep = '', sexo = '', tip_colab = '', cod_funcao = 1{SC_DB_ERROR_CLS}Close{SC_DB_ERROR_END}

Bom, acho que descobri o problema. Mas agora tem outra questão. Eu gostaria de usar apenas um INSERT pra inserir todos os ítens que estão no array, e pelo visto só está gravando o último ítem. Vejam como ficou o código:

// Pegando o arquivo com caminho
$caminho = $this->Ini->path_doc;
$arq = $caminho.'/'.{arquivo};

// Processando a leitura
$fp = fopen($arq,'r');

// Pegando a primeira linha (cabeçalho)
$linha = fgets($fp);

// Pegando o caracter separador na coluna 5
$caracter = substr($linha,5,1);

// Processando arquivo
while (( $linha = fgets($fp) )!==false)
{
     $campos = explode($caracter,$linha);
     $insert_campos = array("chaveagente     = '$campos[0]'",
                            "nome_loj        = '$campos[2]'",
                            "nome_func       = '$campos[3]'",
                            "dat_nascimento  = '".substr($campos[5],6,4).'-'.substr($campos[5],3,2).'-'.str_pad(substr($campos[5],0,2),2,'0',STR_PAD_LEFT)."'",
                            "celular         = '$campos[6]'",
                            "fone_comercial  = '$campos[7]'",
                            "fone_residencia = '$campos[8]'",
                            "cpffunc         = '".preg_replace('#[^0-9]#', '', $campos[9])."'",
                            "situacao        = ".($campos[15]=='ATIVO' ? 0 : 1),
                            "identidade      = '$campos[17]'",
                            "uf_emissor      = '$campos[18]'",
                            "endereco        = '$campos[19]'",
                            "bairro          = '$campos[20]'",
                            "cidade          = '$campos[21]'",
                            "cep             = '$campos[22]'",
                            "sexo            = '$campos[26]'",
                            "tip_colab       = '$campos[4]'",
                            "cod_funcao      = 1");
}

// Inserir registros
$insert_tabela  = 'tab_func';
$insert_sql = 'INSERT ' . $insert_tabela
            . ' SET '   . implode(', ', $insert_campos);
sc_exec_sql($insert_sql);

fclose($fp);

Alguma sugestão para se usar apenas un INSERT neste caso?

Bom, quando a gente não sabe ou tá em dúvida, pede ajuda aos colegas. Quando ninguém se manifesta, talvez seja porque ninguém fez algo do tipo. Então fui queimar pestanas e descobri o problema e a solução. Tudo funcionando 100%.

Kleyber,

Pode postar a solução?

Alcides,

Segue código:

// Pegando o arquivo com caminho
$caminho = $this->Ini->path_doc;
$arq = $caminho.'/'.{arquivo};

// Processando a leitura
$fp = fopen($arq,'r');

// Pegando a primeira linha (cabeçalho)
$linha = fgets($fp);

// Pegando o caracter separador na coluna 5
$caracter = substr($linha,12,1);

// Processando arquivo
while ($dados = fgetcsv($fp, filesize($arq), $caracter))  
    $tabela[] = $dados; 
 
fclose($fp);

$insert_sql = 'INSERT INTO tab_lojas ('
             .'nome_loj,endereco,bairro,cidade,uf_loja,cep,fone,fax,email,'
	         .'gerente,dat_inicial,situacao,dat_inativa,codempresa) VALUES';

foreach ($tabela as $campo) 
{
  if (empty($campo[1])) {
     break;
  }
  $check_sql = 'SELECT * FROM tab_lojas '
             . ' WHERE nome_loj = "'.$campo[0].' - '.$campo[1].'"';
  sc_select(dataset, $check_sql);
  if (false == {dataset})     // Error while accessing database
  {
     sc_error_message('Erro durante acesso ao TAB_LOJAS.');
  }
  elseif (!{dataset}->EOF)   // Existe na tabela
  {
     continue;
  }
  elseif ({dataset}->EOF)   // Não existe na tabela
  {
     $nome_loj = $campo[0]." - ".$campo[1];
     $endereco = '';
     $bairro = '';
     $cidade = $campo[3];
     $uf_loja = $campo[2];
     $cep = '';
     $fone = '';
     $fax = '';
     $email = '';
     $gerente = '';
     $dat_inicial = '0000-00-00';
     $situacao = 0;
     $dat_inativa = '0000-00-00';	 
	 $cod_empresa = 1;
	 
	    // Monta a parte de inserção dos campos
     $insert_sql2 = " ('".$nome_loj."','".$endereco."','".$bairro."','".$cidade."','".$uf_loja."','".$cep."',";
     $insert_sql2 .= "'".$fone."','".$fax."','".$email."','".$gerente."','".$dat_inicial."',".$situacao.",";
     $insert_sql2 .= "'".$dat_inativa."',".$cod_empresa."),";
     $insert_sql .= $insert_sql2;
  }
}	
if (empty($insert_sql2)) {
   sc_error_message("Não há registros a atualizar, verifique");
}
else {
// Tira o último caractere (vírgula extra)
   $insert_sql = substr($insert_sql, 0, -1);

// Inserir registros
   sc_exec_sql($insert_sql);

// Pega o número de registros inseridos
   $cadastrados = mysql_affected_rows();
   sc_error_message("Lojas cadastradas: " . $cadastrados);
}

Kleyber,

Pode me explicar melhor o teu código?
Quando tento importar o .csv sempre da o erro “Não há registros a atualizar, verifique”.

Este código serve para atualizar os dados já existentes no banco ou serve para incluir?

Cadastrei um diretamente no banco para ver se ele atualizava, mas não funcionou.

Criei um csv com as colunas:
nome_loj
endereco
bairro
cidade
uf_loja
cep
fone
fax
email
gerente
dat_inicial
situacao
dat_inativa
codempresa

Alcides,

A rotina verifica se os registros (linhas) que estão no arquivo CSV já existem na tabela. Se já existirem, a mensagem “Não há registros a atualizar, verifique” aparece. Se não houver nenhum registro na tabela, ele irá incluir.

Kleyber,

Desculpa, devo estar fazendo alguma coisa errado, pois mesmo sem dados na tabela a mensagem é a mesma.

Não sei como resolver…

Alcides,

Confira se a tabela tem exatamente os mesmos campos do arquivo CSV. Qualquer coisa, coloca aqui o teu código, a descrição do teu CSV e a descrição da tabela para analisarmos.

Tem que dividir em partes pra fazer debug, primeiro abra o arquivo fopen e liste os campos usando echo, ai coloque o comando;
break; no final para ver o resultado.

Ok, Testada a etapa 1.

Etapa 2
Criar a rotina para ver se o registro já existe testar ela igualmente com o break.

Etapa 3.
Fazer a macro que insere o registro manualmente e tentar inserir 1, colocar o break; para checar o código.

Etapa 4.
Finalizar tudo, que já esta resolvido.


Divisão e conquista

Origem: Wikipédia, a enciclopédia livre.

Divisão e Conquista (do inglês Divide and Conquer) em computação é uma técnica de projeto de algoritmos utilizada pela primeira vez por Anatolii Karatsuba em 1960 no algoritmo de Karatsuba.

Esta técnica consiste em dividir um problema maior recursivamente em problemas menores até que o problema possa ser resolvido diretamente. Então a solução do problema inicial é dada através da combinação dos resultados de todos os problemas menores computados. Vários problemas podem ser solucionados através desta técnica, como o da ordenação de números através do algoritmo merge sort e da transformação discreta de Fourier através da transformada rápida de Fourier. Outro problema clássico que pode ser resolvido através desta técnica é a Torre de Hanoi.

A técnica soluciona o problema através de três fases:
1.Divisão: o problema maior é dividido em problemas menores e os problemas menores obtidos são novamente divididos sucessivamente de maneira recursiva.
2.Conquista: o resultado do problema é calculado quando o problema é pequeno o suficiente.
3.Combinação: o resultado dos problemas menores são combinados até que seja obtida a solução do problema maior.

Eficiência

Problemas que utilizam esta técnica podem tirar proveito de máquinas com múltiplos processadores pois a fase de divisão em problemas menores proporciona uma divisão natural do trabalho. Cada um dos problemas menores obtidos pode ser calculado separadamente em um processador sem depender dos demais.

A solução por esta técnica também é eficiente no uso da memória cache pois ao final da fase de divisão grande parte dos dados necessários para a fase de combinação já estão disponíveis na cache proporcionando um acesso mais veloz aos dados. Porém o caráter recursivo das soluções acaba gerando um trabalho de processamento maior devido ao uso de chamadas recursivas e o uso da pilha de chamadas.

** Todos esses macetes e muito mais, aprendi na faculdade de Analises de sistemas.

Kleyber,

Esta é a tabela:

CREATE TABLE IF NOT EXISTS tab_lojas (
nome_loj int(11) NOT NULL,
endereco varchar(45) DEFAULT NULL,
bairro varchar(45) DEFAULT NULL,
cidade varchar(45) DEFAULT NULL,
uf_loja varchar(45) DEFAULT NULL,
cep varchar(45) DEFAULT NULL,
fone varchar(45) DEFAULT NULL,
fax varchar(45) DEFAULT NULL,
email varchar(45) DEFAULT NULL,
gerente varchar(45) DEFAULT NULL,
dat_inicial datetime DEFAULT NULL,
situacao varchar(45) DEFAULT NULL,
dat_inativa datetime DEFAULT NULL,
codempresa varchar(45) DEFAULT NULL,
PRIMARY KEY (nome_loj)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

O CSV exportei da tabela via phpMyAdmin.

nome_loj endereco bairro cidade uf_loja cep fone fax email gerente dat_inicial situacao dat_inativa codempresa

O código é o teu que estou tentando fazer funcionar, funcionando vou adaptar para a tabela que realmente preciso.

Agradeço a ajuda desde já.

Alcides,

O teu CSV tem registros? Pelo que você mostrou não tem nenhum.

OBS.: As observações do Jailton são super válidas. A rotina funciona muito bem aqui, mas por algum motivo pode não estar funcionando pra você e então se deve fazer a verificação por etapas.

Kleyber,

Estes são os dados do csv:

nome_loj endereco bairro cidade uf_loja cep fone fax email gerente dat_inicial situacao dat_inativa codempresa
1 1 3 3 3 3 3 3 3 1 0000-00-00 00:00:00 0 0000-00-00 00:00:00 1

Alcides,

nome_loj, endereco,bairro,cidade,uf_loja são casos de campos alfanuméricos. Você colocou números no teu CSV. Experimente colocar dados nesse CSV que correspondam aos campos em questão.

Kleyber,

Coloquei dados e funcionou, obrigado!

nome_loj endereco bairro cidade uf_loja cep fone fax email gerente dat_inicial situacao dat_inativa codempresa
Nilo Nilo peçanha chacara das pedras Porto Alegre RS 94070060 5133274455 5133274456 fff@terra.com 1 0000-00-00 00:00:00 0 0000-00-00 00:00:00 1

Jailton,

Obrigado, vou guardar esta dica!

na importação esta acusando uma mensagem:

pg_query(): Query failed: ERROR: column “nilo;nilo;chacara;porto;RS;94070060;5133274455;5133274456;fff@t” does not existLINE 1: SELECT * FROM tab_lojas WHERE nome_loj = "nilo;nilo;chacara… ^
Erro durante acesso ao TAB_LOJAS.
Não há registros a atualizar, verifique

“Não há registros a atualizar, verifique”