PostgreSQL Tipo Serial e PDO::lastInsertId()

420 views
Skip to first unread message

EduRibeiro

unread,
Sep 2, 2010, 1:05:34 PM9/2/10
to PHP MS
Pessoal boa tarde!

Alguem ai sabe se tem como recuperar o id do último registro inserido
com PDO usando a função pdo::lastInsertId() quando o tipo do campo é
SERIAL . Estou usando postgresql.

Tento pegar o último id e ele retorna vazio.

$pdo->lastInsertId();

Alguem ai sabe o problema ou tem uma solução ?

Eu não queria fazer SELECT max(id) .......

Jorge Vilela

unread,
Sep 2, 2010, 4:19:47 PM9/2/10
to ph...@googlegroups.com
Daew playboy, passa a sequence:

$db->lastInsertId("tabela_id_seq")


Jorge Vilela


2010/9/2 EduRibeiro <eduribe...@gmail.com>

--
Você recebeu esta mensagem porque está inscrito no Grupo "phpms" em Grupos do Google.
 Para postar neste grupo, envie um e-mail para ph...@googlegroups.com
 Para cancelar a sua inscrição neste grupo, envie um e-mail para phpms-un...@googlegroups.com
 Para ver mais opções, visite este grupo em http://groups.google.com/group/phpms?hl=pt-PT
Para acessar o site do grupo, visite: http://www.phpms.org/
As regras de utilização deste grupo encontram-se em: http://www.phpms.org/regras-da-lista

Humberto Pereira

unread,
Sep 2, 2010, 4:21:51 PM9/2/10
to ph...@googlegroups.com
Nao use max(id), se alguem inserir outro dado antes de dar tempo de vc
fazer a outra consulta, vc vai pegar o id errado. P/ pegar o id que
acabou de ser inserido use a funcao currval.

SELECT currval('nome_da_sequencia');

P/ vc nao ter que ficar adivinhando o nome da sequencia, o postgresql
tem uma funcao chamada pg_get_serial_sequence, que te retorna o nome
da sequencia caso o campo seja serial.

SELECT currval(pg_get_serial_sequence('tabela', 'id'));

Nesse link tem algumas informacoes bem legais sobre isso.
http://neilconway.org/docs/sequences/

[]s
Begnini

2010/9/2 EduRibeiro <eduribe...@gmail.com>:

Eduardo Ribeiro Lima

unread,
Sep 2, 2010, 4:57:51 PM9/2/10
to ph...@googlegroups.com
Fala Jorgieeee oo faz tempo emm !! E ai ja pegou o diploma???

O mano então tinha feito isso ai q vc falou e deu certo, mais a preocupação é de ter varios usuários fazendo a mesma operação ao mesmo tempo e pegar o id errado .

O vamo combina ai de fazer alguma coisa com o renan e a carolzonaa. Ou vc ainda fica naquela de jogar em rede com seus amigos playboys no sábado ou fica andando de jipe sem ter um eheheheheheh ??  

Eduardo Ribeiro Lima

unread,
Sep 2, 2010, 4:54:11 PM9/2/10
to ph...@googlegroups.com
Humberto uma das preocupações era de pegar o id errado caso ocorra uma concorrência de múltiplos usuários fazendo a mesma operação ao mesmo tempo.

A funçã do PDO lastInsertId  não faz a mesma coisa q vc falouda função currval ?

Humberto Pereira

unread,
Sep 2, 2010, 8:04:23 PM9/2/10
to ph...@googlegroups.com
Toda vez que alguem acessa sua pagina, voce provavelmente cria uma
conexao com o banco, faz algumas operacoes com SQL e mostra o HTML
final p/ o usuario.

Pois bem, cada vez que voce faz isso, voce cria uma coisa chamada
sessao com o banco. Essa sessao existe desde a chamada do seu
pg_connect (ou new PDO()) ateh qdo vc chama um pg_close (ou
PDO::__destruct), que sao chamados quando o seu script termina, caso
voce nao os tenha chamados explicitamente.

Se durante uma sessao, voce pega um valor de uma sequencia (inserindo
nulo em um campo default nextval('sequencia'), por ex.), esse valor
fica gravado durante aquela sessao. Se existirem mil usuarios
inserindo ao mesmo tempo, cada um tera sua propria sessao e seu
proprio valor da sequencia.

Resumindo, nao tem como isso acontecer, a nao ser que o banco de dados
esteja com algum bug.

[]s
Begnini

2010/9/2 Eduardo Ribeiro Lima <eduribe...@gmail.com>:

Eduardo Ribeiro Lima

unread,
Sep 2, 2010, 10:55:38 PM9/2/10
to ph...@googlegroups.com
Humberto muito obrigado pela explicação. Vou dar uma lida mais sobre conexões concorrentes.

Valeu mesmo !!

Jorge Vilela

unread,
Sep 3, 2010, 9:05:05 AM9/3/10
to ph...@googlegroups.com
Humberto, eu acho que não é bem assim...

Mas enfim, Eduardo se quer ter certeza faça uma stored procedure +- assim:

CREATE OR REPLACE FUNCTION "public"."minhafuncao" (pnome varchar) RETURNS integer AS
$body$
DECLARE
    minhaseq integer;
BEGIN
select into minhaseq nextval(pg_get_serial_sequence('tabela', 'id')); -- Ou select into minhaseq nextval('sequence_da_tabela')
        insert into tabela (id, nome) values (minhaseq, p_nome);
        return minhaseq;
END;
$body$
LANGUAGE 'plpgsql';


Ou no PHP mesmo faça um select na nextval e use o resultado no insert, depois aproveite a variável com o valor usado no id para fazer o que você precisa


Jorge Vilela

Humberto Pereira

unread,
Sep 3, 2010, 9:43:46 AM9/3/10
to ph...@googlegroups.com
Eh facil voce provar se eh ou nao assim.

Faca 2 conexoes com o banco (2 psql, por ex.). Crie uma tabela com um
campo serial. Insira nessa tabela na conexao 1 e pegue o currval da
sequencia. Insira na conexao 2 e pegue o currval da sequencia tambem.
Agora volte a conexao 1, selecione o currval da mesma sequencia de
novo e veja se o valor mudou.

Se tiver mudado, realmente o que eu disse nao funciona. Mas se nao
tiver mudado, funciona sim.

Banco de dados sao feitos p/ facilitar sua vida, p/ q vc nao tenha que
ficar pensando em problemas desse tipo. Ele deve ser capaz de
gerenciar concorrencia e manter integridade sem problemas. Se ele nao
faz isso, ou nao faz bem, eh melhor voce pensar seriamente em trocar
de banco.

[]s
Begnini

2010/9/3 Jorge Vilela <jorge....@gmail.com>:

Eduardo Green

unread,
Sep 3, 2010, 11:27:54 AM9/3/10
to ph...@googlegroups.com
Vou fazer o teste !!!!

Eduardo R. Lima
C: 9106-8090
 





Date: Fri, 3 Sep 2010 09:05:05 -0400
Subject: Re: [phpms] PostgreSQL Tipo Serial e PDO::lastInsertId()
From: jorge....@gmail.com
To: ph...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages