Às vezes é útil obter dados das linhas modificadas enquanto elas
estão sendo manipuladas.
Os comandos INSERT, UPDATE,
DELETE e MERGE possuem a
cláusula opcional RETURNING que permite fazer isto.
O uso de RETURNING evita realizar uma consulta
adicional ao banco de dados para coletar os dados, sendo
particularmente valioso quando, de outra forma, seria difícil
identificar as linhas modificadas de forma confiável.
O conteúdo permitido para a cláusula RETURNING é o
mesmo da lista de saída do comando SELECT
(veja a Seção 7.3).
Pode conter nomes de coluna da tabela de destino do comando, ou
expressões de valor usando essas colunas. Uma forma abreviada comum é
RETURNING *, que seleciona todas as colunas da
tabela de destino em ordem.
No comando INSERT, os dados padrão disponíveis para
RETURNING são os da linha na forma como foi inserida.
Isto não é tão útil em inserções triviais, porque apenas repete os
dados fornecidos pelo cliente, mas pode ser muito útil na presença de
valores padrão calculados. Por exemplo, ao se usar a coluna
serial para
fornecer identificadores únicos, RETURNING
pode retornar o ID atribuído à nova linha:
CREATE TABLE usuarios (primeiro_nome text, ultimo_nome text, id serial primary key);
INSERT INTO usuarios (primeiro_nome, ultimo_nome) VALUES ('Joe', 'Cool') RETURNING id;
id ---- 1 (1 linha) INSERT 0 1
A cláusula RETURNING também é muito útil com
INSERT ... SELECT.
No comando UPDATE, os dados disponíveis para
RETURNING são os do novo conteúdo da linha modificada.
Por exemplo:
UPDATE produtos SET preco = preco * 1.10 WHERE preco <= 99.99 RETURNING nome, preco AS novo_preco;
nome | novo_preco --------+------------ Queijo | 10.9890 (1 linha) UPDATE 1
No comando DELETE, os dados padrão disponíveis para
RETURNING são os do conteúdo da linha excluída.
Por exemplo:
DELETE FROM produtos WHERE nome = 'Queijo' RETURNING *;
num_produto | nome | preco
-------------+--------+---------
1 | Queijo | 10.9890
(1 linha)
DELETE 1
No comando MERGE, os dados padrão disponíveis para
RETURNING são o conteúdo da linha de origem mais
o conteúdo da linha inserida, atualizada ou excluída.
Como é muito comum que as linhas de origem e de destino tenham muitas
colunas idênticas, especificar RETURNING *
pode produzir muitas colunas duplicadas, portanto geralmente é mais
útil qualificá-lo para que retorne apenas a linha de origem
ou de destino. Por exemplo:
INSERT INTO produtos VALUES (1, 'Queijo', 9.99); INSERT INTO novos_produtos VALUES (1, 'Leite', 4.99); INSERT INTO novos_produtos VALUES (2, 'Açúcar', 3.99); MERGE INTO produtos p USING novos_produtos n ON p.num_produto = n.num_produto WHEN NOT MATCHED THEN INSERT VALUES (n.num_produto, n.nome, n.preco) WHEN MATCHED THEN UPDATE SET nome = n.nome, preco = n.preco RETURNING p.*;
num_produto | nome | preco
-------------+--------+-------
1 | Leite | 4.99
2 | Açúcar | 3.99
(2 linhas)
MERGE 2
Em cada um destes comandos, também é possível retornar explicitamente o conteúdo antigo e o novo da linha modificada. Por exemplo:
UPDATE produtos SET preco = preco * 1.10
WHERE preco <= 99.99
RETURNING nome, old.preco AS preco_antigo, new.preco AS preco_novo,
new.preco - old.preco AS mudanca_preco;
nome | preco_antigo | preco_novo | mudanca_preco --------+--------------+------------+--------------- Leite | 4.99 | 5.4890 | 0.4990 Açúcar | 3.99 | 4.3890 | 0.3990 (2 linhas) UPDATE 2
No exemplo acima, escrever new.preco é a mesma
coisa que escrever apenas preco, mas isto torna o
significado mais claro.
Esta sintaxe para retornar valores antigos e novos está disponível
nos comandos INSERT, UPDATE,
DELETE e MERGE, mas normalmente
os valores antigos serão NULL para o comando
INSERT, e os novos valores serão
NULL para o comando DELETE.
Entretanto, existem situações em que new. ainda
pode ser útil para estes comandos.
Por exemplo, em um comando INSERT contendo a cláusula
ON CONFLICT DO UPDATE,
os valores antigos serão não-NULL para as linhas
conflitantes.
De forma semelhante, se um comando DELETE se tornar
um comando UPDATE devido a uma
regra de reescrita,
os novos valores serão não-NULL.
Se houver gatilhos (veja o Capítulo 37) na tabela de
destino, os dados disponíveis para RETURNING serão
os da linha modificada pelos gatilhos.
Assim, inspecionar colunas computadas por gatilhos é outro caso de
uso comum para RETURNING.