Ir para conteúdo
Fórum Script Brasil
  • 0

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


JaguA

Pergunta

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'=>'jagua@email.com');
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@email.com');
$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;
    }
}
?>

Editado por JaguA
Link para o comentário
Compartilhar em outros sites

8 respostass a esta questão

Posts Recomendados

  • 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...

Editado por JaguA
Link para o comentário
Compartilhar em outros 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.

Link para o comentário
Compartilhar em outros 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..

Link para o comentário
Compartilhar em outros 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 );
   }


}

Editado por jissa
Link para o comentário
Compartilhar em outros 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...

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...