• 0
Sign in to follow this  
JaguA

[Resolvido]Problema para recupera ultimo ID registrado PDO->lastIns

Question

Bem eu to com um problema bem chato de resolver, preciso que apos fazer um cadastro me retorne o Id do qual foi feito esse cadastro.

sendo asim o lastInsertId...

bem já pesquisei bastante a respeito dele e sendo rapido eu so preciso ter minha conexao istanciada e pedir a funcao do lastInsertId.

minha funcao de cadastro é esta.

public function insert($tabela, $string) {
        

   $func = new FuncoesDB;   
   $func->setTabela($tabela);
   $func->setCampos($string);
   $func->setValues($string);
 //$this->valores = $func->setValores($string);
   $this->string = $func->cadastrar(); 
   
$oConexao = Conexao::getInstance();
try{
    //executa a instrução de consulta
    $oConexao->beginTransaction();

    $stmt = $oConexao->prepare("$this->string")->execute($string); 
    
    $oConexao->commit();

}catch (PDOException $e){
    $oConexao->rollBack();
    echo $e->getMessage();
                        }
                     
}
para uma exemplificação melhor este comando
$stmt = $oConexao->prepare("$this->string")->execute($string);
é isso sem as variaveis.
$stmt = $oConexao->prepare("INSERT INTO usuarios (nome,email) VALUES (:nome, :email) ")->execute('nome'=>'Jagua','email'=>'[email protected]');
beleza... desta forma esta funcionando tranquilo se eu coloco a seguinte linha
$ultimoId = $oConexao->lastInsertId();
return $ultimoId;
ele me retorna o Id mas não faz o cadastro a cada cadastro ele conta + 1id no banco so que não faz o registro.. n aparece os dados somente o aumento de Index no autoincrement se eu tirar e fizer o registro, o registro aparece no banco normal so que com o Id que estava por vir mim ... vamos supor eu fiz o teste sem o lastInsertId 3 vezes então tenho 3 registro 1 2 3 agora fiz mais 3 teste com ele (não tenho nad novo) agora fiz o teste novamente + 1 sem o lastInsertId 1237 agora tenho 4 registro e o registro-4 é Id7 que é a sequencia do Increment. para fazer o cadastro do o seguinte comando.
include '_a/_class/class.Cadastro.php';

$teste = New Cadastro();
$string = array('nome'=>'Teste','email'=>'[email protected]');
$ultimoId = $teste->insert('usuarios', $string);
echo $ultimoId;
minha class de conexao é esta.
<?php
########################################################
######Configuração para conectar ao Banco de Dados.#####
########################################################

class Conexao extends PDO {

    private static $instancia;

    public function Conexao($dsn, $username = "", $password = "") {
        // O construtro abaixo é o do PDO
        parent::__construct($dsn, $username, $password);
    }

    public static function getInstance() {
        // Se o a instancia não existe eu faço uma
        if(!isset( self::$instancia )){
            try {
                self::$instancia = new Conexao("mysql:host=localhost;dbname=test", "root", "");
                self::$instancia->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            } catch ( Exception $e ) {
                echo 'Erro ao conectar';
                exit ();
            }
        }
        // Se já existe instancia na memória eu retorno ela
        return self::$instancia;
    }
}
?>

Edited by JaguA

Share this post


Link to post
Share on other sites

8 answers to this question

Recommended Posts

  • 0

voce tentou dar o commit antes dele??

faz um teste

$oConexao->commit();

$ultimoId = $oConexao->lastInsertId();

return $ultimoId;

se colocar o latinserID antes do commit ele vai retornar zero

Share this post


Link to post
Share on other sites
  • 0

jissa,

tem algo muito estranho fiz 2 testes e não saio de acordo com o esperado.

Primeiro Teste

try{
    //executa a instrução de consulta
    $oConexao->beginTransaction();
     
    $stmt = $oConexao->prepare("$this->string")->execute($string);
    $oConexao->commit();
    $ultimoId = $oConexao->lastInsertId();
    return $ultimoId;
    
}
Resultado -> Efetuado o registro no banco, Retorno ID->0 Segundo Teste
try{
    //executa a instrução de consulta
    $oConexao->beginTransaction();
     
    $stmt = $oConexao->prepare("$this->string")->execute($string);
    
    $ultimoId = $oConexao->lastInsertId();
    return $ultimoId;
    
    $oConexao->commit();
    
}

Resultado -> Não houve registro no banco, Retorno ID->15 (Id do registro do teste anterior foi 14)

Isso é mais estranho ainda, já que o certo seria somente apos o commit() ele me passa o valor...

Edited by JaguA

Share this post


Link to post
Share on other sites
  • 0

Fiz uma alteração afim de obter uma resposta quanto a utilização do array.

então fiz desta forma.

$stmt = $oConexao->prepare("$this->string")->execute();
    var_dump($stmt);
    $oConexao->commit();
eu dei um var_dump na $stmt e ele retornou true e o registro foi efetuado . depois acrescentei as linhas
$ultimoId = $oConexao->lastInsertId();
    return $ultimoId;
e ficou desta forma
$stmt = $oConexao->prepare("$this->string")->execute();
    var_dump($stmt);
    $oConexao->commit();
$ultimoId = $oConexao->lastInsertId();
    return $ultimoId;
Ele me retornou True e fez o registro. e o Id retornado foi 0 depois testei alternando. ficando assim.
$stmt = $oConexao->prepare("$this->string")->execute();
    var_dump($stmt);
    
$ultimoId = $oConexao->lastInsertId();
    return $ultimoId;
$oConexao->commit();

Retornou True, não fez o registro e me retornou o Id corretamente.

Eu queria entende como isso é possivel se ele devia retorna o Id somente depois do commit ...

PS: eu tentei sem o prepare colocando um query e exec somente o query diretamente com o exec. mas todos deram no mesmo processo já citado.

Share this post


Link to post
Share on other sites
  • 0

muito estranho mesmo..

será que não tem nenhum commit antes em algum outro script

voce já usou a função em outro lugar de seu codigo?? pode até ser um bug do php

Share this post


Link to post
Share on other sites
  • 0

Jissa

eu não usei ela em nenhum outro lugar este é o unico no qual preciso retornar o ultimo ID cadastrado.

Willian

nos exemplos não se ve uma utilização do commit() de qualquer forma eu já tentei destes modos e não me deu o resultado esperado... eu vou criar outra class de conexão mais simples e direta e coloca opção do lastInsertId junto na classe de conexao como nos exemplos para ver se retorna corretamente..

Share this post


Link to post
Share on other sites
  • 0

eu uso uma classe aqui caseira..

a muito tempo 2005 o luciano começou esta classe, alterei alguma coisa. da uma olhada.. se caso usar e implementar/melhorar algo a vontade.. e avise :)

uso ela e tem um bom retorno.. simples e pratica, a ideia é usar para MySql e PostGree, se não passar nada assume o mysql como pradrao

conexao:

$bd = new bd( 1 ); //define se mysql 1 postgree 2
$bd->conecta( $host, $user, $senha, $db, "" );
exemplo de uso:
$sql = $bd->executa( "Select * from TABELA where id = '$id'" );
$dados = $bd->dados( $sql );
classe classBd.php
<?
/*
Classe que faz a conexão com um Banco de Dados e cria funções
próprias ao invés de deixar as originais, dessa forma pode-se
utilizar qualquer Banco usando-se as mesmas funções

**---------------------------------------------------------------**
-function bd( $banco )
construtor que recebe como parâmetro o tipo de Banco de Dados
1 - Mysql, 2 - PostgreSql(ainda não testado)

-function conecta( $host, $user, $senha, $db, $porta )
método que faz a conexão com o Banco de Dados

-function executa( $sql )
método que executa uma query

-function dados( $res )
método que coloca $res num array de resultados

-function ultimo_id()
retorna o último id inserido

-function numero_campos( $res )
retorna o número de campos encontrados na query

-function nome_campo( $res, $indice )
retorna o nome do campo

-function tipo_campo( $res, $indice )
retorna o tipo do campo

**---------------------------------------------------------------**

*/

Class bd
{
   Var $id;            //identificador da conexão com o Banco
   Var $bd;            //1 - Mysql, 2 - PostgreSql
   Var $res;           //guarda o resultado da query
   Var $nrw;           //guarda o número de registros encontrados
   
   //contrutor define o Banco
   function bd( $banco )
   {
      if( $banco == 1 || $banco == 2 )
         $this->bd = $banco;
      else
         $this->bd = 1;
   }
   
   //método que faz a conexão
   function conecta( $host, $user, $senha, $db, $porta )
   {
      if( $this->bd == 1 ) //se for Mysql
      {
         $this->id = mysql_connect( $host, $user, $senha ) or die ( "Erro de Conexão: ".mysql_error() );
         if( $this->id )
            mysql_select_db( $db, $this->id );
      }
      else //se for PostgreSql
      {
         $this->id = pg_connect( "host=$host dbname=$db user=$user password=$senha" ) or die ( "Erro de Conexão: ".pg_result_error( $this->id ) );
      }
   
   }
   
   //método que executa uma query
   function executa( $sql )
   {
      if( $this->bd == 1 ) //se é Mysql
      {
         $this->res = mysql_query( $sql, $this->id ) or die ( "Erro ao executar a query: ".mysql_error( $this->id) );
         $this->nrw = @mysql_num_rows( $this->res );
      }
      else //se for PostgreSql
      {
         $this->res = pg_query( $this->id, $sql ) or die ( "Erro ao executar a query: ".pg_result_error( $this->id) );
         $this->nrw = @pg_num_rows( $this->res );
      }
      return $this->res;
   }
   
   //método que retorna os registros encontrados
   function dados( $res )
   {
      if( $this->bd == 1 ) //se é Mysql
         return mysql_fetch_array( $res );
      else //se for postgreSql
         return pg_fetch_array( $res );
   }
   
   //método que devolve o último id gerado
   function ultimo_id()
   {
      if( $this->bd == 1 ) //se é MySql
         return mysql_insert_id();

   }
   
   //método que retorna o número de campos encontrados em $res
   function numero_campos( $res )
   {
      if( $this->bd == 1 )
         return mysql_num_fields( $res );
   }
   
   //método que retorna o nome do campo
   function nome_campo( $res, $indice )
   {
      if( $this->bd == 1 )
         return mysql_field_name( $res, $indice );
   }
   
   //método que retorna o tipo do campo
   function tipo_campo( $res, $indice )
   {
      if( $this->bd == 1 )
         return mysql_field_type( $res, $indice );
   }
   
   //método que pega o valor de um determinado campo num determinado índice
   function valor( $res, $indice, $campo = "" )
   {
      if( $this->bd == 1 )
         if( $campo )
            return @mysql_result( $res, $indice, "$campo" );
         else
            return @mysql_result( $res, $indice );
   }


}

Edited by jissa

Share this post


Link to post
Share on other sites
  • 0

Bem, eu consegui resolver o problema, mas não de uma forma agradavel, até porque não descobri o porque de não funcionar.

mas vamos lá...

Primeiro minha conexão não esta mais extends e eu crie a funcao de cadastro aqui dentro ela ficou assim agora.

<?php
########################################################
######Configuração para conectar ao Banco de Dados.#####
########################################################

class Conexao {

    private  $instancia;

    

    public function conecta() {
        
               $instancia = new PDO("mysql:host=localhost;dbname=test", "root", "");
               $instancia->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

   }


    public function cadastro($string) {

$instancia->exec($string);
$Id = $instancia->lastInsertId();

return $Id;

}
?>
bem minha classe de cadastro ficou desta forma agora.
public function insert($tabela, $string) {
        

   $func = new FuncoesDB;  
   $func->setTabela($tabela);
   $func->setCampos($string);
   $func->setValues($string);
//$this->valores = $func->setValores($string);
   $this->string = $func->cadastrar();

   $oConexao = new Conexao();
   $Id = $oConexao->cadastro($string);
   return $Id;
                    
}

Bem resumindo.. colocando o exec dentro da class de conexao e simplificando a minha conexao deu tudo certo... mas ainda não ficou do meu agrado, pois eu já havia montado aquela estrutura de Conexão e cadastro e tive que remove-la para atende a minah nescessidade, vou continuar pesquisando e tenta implementar da forma em que pretendo rsrs...

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this