Matheus/ Flávio, mataram na mosca! 

A solução 3 (aqui numerada como
3) é a que estava procurando. Muito mais "elegante" rs rs 

Obrigado


Eduardo Az 

Em 22.10.2015 16:24, Matheus de Oliveira escreveu: 

>
2015-10-21 12:03 GMT-02:00 Eduardo Az - EMBRASIS
<[email protected]>:
> 
>> -como ID é serial, via select vejo o
ultimo registo com o max()
> 
> Ok. Muita resposta, posso resumir?
Existem, que eu saiba, ao menos 3 opções confiáveis para isso (duas
foram comentadas). Vou mostrar um pseudo-código baseado em PL/pgSQL...
>

> Solução 1: antes de inserir na tabela de pedidos você chama
manualmente a função nextval e salva o valor gerado:
> 
> SELECT
nextval(pg_get_serial_sequence('pedidos', 'id')) INTO v_id;
> 
> -- use
o valor salvo na variável para inserir na pedidos:
> 
> INSERT INTO
pedidos(id, funcionario, ...) VALUES(v_id, p_funcionario, ...);
> 
> --
Na hora de inserir na pedido_itens (para cada item):
> 
> INSERT INTO
pedido_itens(id_pedido, id_produto, ...) VALUES(v_id, p_produto, ...);
>

> Solução 2: após inserir em pedidos, use a função currval para
recuperar o valor:
> 
> -- Inserir na pedidos normalmente (veja que não
referencio o "id", mas também poderia usar o DEFAULT):
> 
> INSERT INTO
pedidos(funcionario, ...) VALUES(p_funcionario, ...);
> 
> -- Busca o
valor gerado usando a função currval
> 
> SELECT
currval(pg_get_serial_sequence('pedidos', 'id')) INTO v_id;
> 
> -- Aqui
é igual à anterior:
> INSERT INTO pedido_itens(id_pedido, id_produto,
...) VALUES(v_id, p_produto, ...);
> 
> Solução 3: use a cláusula
RETURNING do comando INSERT:
> 
> -- Inserir na pedidos e já recupera o
valor gerado, numa só tacada:
> 
> INSERT INTO pedidos(funcionario, ...)
VALUES(p_funcionario, ...)
> 
> RETURNING id INTO v_id;
> 
> -- Aqui é
igual à anteriores:
> INSERT INTO pedido_itens(id_pedido, id_produto,
...) VALUES(v_id, p_produto, ...); 
> 
> Na minha opinião, a solução 3 é
sem dúvida a melhor. Por vários motivos:
> 
> 1. Não precisa duas idas
ao servidor, em uma tacada só já faz o INSERT e recupera o valor gerado;

> 2. Evita qualquer erro que possa acontecer caso seja gerado um novo
id pela sequence na mesma sessão (só seria possível vai trigger, nesse
caso, mas já vi acontecer); 
> 3. Não precisa se preocupar com o nome da
sequence, na verdade nem precisa se preocupar com sua existência; 
> 4.
Funciona mesmo que troque o modelo para gerar "id" (comum acontecer
quando tem-se mais de um servidor de banco); 
> ... deve ter mais ... 
>

> OBS: A função pg_get_serial_sequence recupera o nome da sequence que
foi criada usando o tipo serial ou OWNED BY. Acho mais simples e
confiável que usar o nome da sequence. Tudo bem que a solução 3, minha
preferida, nem precisamos de nos preocupar com a sequence.
> 
> OBS2:
Esse erro é bem comum, infelizmente. Aliás tem vários erros comuns que
são bem simples, veja [1] (nem é merchan... :P ) 
> 
> [1]
http://www.slideshare.net/matheus_de_oliveira/dev-camp2015-top5falsassuposicoesprogramadores
[2] (slide 58 fala sobre esse caso, não é específico de PostgreSQL)
>

> Atenciosamente, 
> -- 
> 
> Matheus de Oliveira
> 
>
_______________________________________________
> pgbr-geral mailing
list
> [email protected]
>
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[1]

 

Links:
------
[1]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[2]
http://www.slideshare.net/matheus_de_oliveira/dev-camp2015-top5falsassuposicoesprogramadores
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a