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
