INSERT

INSERT — Cria novas linhas em uma tabela

Sinopse

[ WITH [ RECURSIVE ] consulta_WITH [, ...] ]
INSERT INTO nome_da_tabela [ AS alias ] [ ( nome_da_coluna [, ...] ) ]
    [ OVERRIDING { SYSTEM | USER } VALUE ]
    { DEFAULT VALUES
    | VALUES ( { expressão
    | DEFAULT } [, ...] ) [, ...] | consulta
    }
    [ ON CONFLICT [ conflito_alvo ] ação_de_conflito ]
    [ RETURNING [ WITH ( { OLD | NEW } AS alias_da_saída [, ...] ) ]
          { * | expressão_de_saída [ [ AS ] nome_de_saída ] }
          [, ...]
    ]

onde conflito_alvo pode ser um entre:

    ( {   nome_da_coluna_de_índice
      | ( expressão_de_índice )
      }
      [ COLLATE ordenação ]
      [ classe_de_operador ] [, ...]
    )
    [ WHERE predicado_de_índice ]
    ON CONSTRAINT nome_da_restrição

e ação_de_conflito é um entre:

    DO NOTHING
    DO UPDATE SET
        {   nome_da_coluna = { expressão | DEFAULT }
        | ( nome_da_coluna [, ...] ) = [ ROW ]
          ( { expressão | DEFAULT } [, ...] )
        | ( nome_da_coluna [, ...] ) = ( sub-SELECT )
        }
        [, ...]
        [ WHERE condição ]

Descrição

O comando INSERT insere novas linhas em uma tabela. Pode-se inserir uma ou mais linhas especificadas por expressões de valor, ou zero, ou mais linhas resultantes de uma consulta.

Os nomes das colunas de destino podem ser listados em qualquer ordem. Se não for fornecida nenhuma lista de nomes de colunas, o padrão será todas as colunas da tabela em sua ordem declarada; ou os primeiros N nomes de coluna, se houver apenas N colunas fornecidas pela cláusula VALUES ou pela consulta. Os valores fornecidos pela cláusula VALUES, ou pela consulta, são associados à lista de colunas explícita ou implícita da esquerda para a direita.

Cada coluna não presente na lista de colunas explícitas ou implícitas será preenchida com o valor padrão, seja seu valor padrão declarado, ou nulo se não houver nenhum.

Se a expressão de alguma coluna não for do tipo de dados correto, será feita uma tentativa de conversão automática de tipo de dados.

Os comandos INSERT em tabelas que não possuem índices de unicidade, não serão bloqueados por atividades concorrentes. As tabelas com índices de unicidade podem ser bloqueadas, se as sessões simultâneas executarem ações que bloqueiam ou modificam as linhas correspondentes aos valores de índice de unicidade que estão sendo inseridos; os detalhes são cobertos na Seção 63.5. A cláusula ON CONFLICT pode ser usada para indicar uma ação alternativa, quando acontece um erro de restrição de unicidade ou de violação de restrição de exclusão. (Veja Cláusula ON CONFLICT abaixo.)

A cláusula opcional RETURNING faz com que o comando INSERT calcule e retorne valor(es) com base em cada linha realmente inserida (ou atualizada, se uma cláusula ON CONFLICT DO UPDATE for usada). Serve principalmente para obter valores que foram fornecidos por padrão, como o número de uma sequência serial. No entanto, é permitida qualquer expressão que utilize as colunas da tabela. A sintaxe da lista da cláusula RETURNING é idêntica à da lista de saída do comando SELECT. Somente as linhas que foram inseridas ou atualizadas com sucesso serão retornadas. Por exemplo, se uma linha foi bloqueada, mas não foi atualizada porque uma cláusula ON CONFLICT DO UPDATE ... WHERE condição não foi satisfeita, a linha não será retornada.

É necessário possuir o privilégio INSERT na tabela para inserir linhas nela. Se a cláusula ON CONFLICT DO UPDATE estiver presente, também é necessário possuir o privilégio UPDATE na tabela.

Se for especificada uma lista de colunas, só é necessário possuir o privilégio INSERT nas colunas listadas. Da mesma forma, quando é especificada a cláusula ON CONFLICT DO UPDATE, só é necessário possuir o privilégio UPDATE na(s) coluna(s) listadas para serem atualizadas. Entretanto, a cláusula ON CONFLICT DO UPDATE também requer o privilégio SELECT em todas as colunas cujos valores são lidos na expressão ou condição da cláusula.

O uso da cláusula RETURNING requer o privilégio SELECT em todas as colunas mencionadas na cláusula. Se for usado o parâmetro consulta para inserir linhas de uma consulta, é claro que será necessário ter o privilégio SELECT em qualquer tabela ou coluna presente na consulta.

Parâmetros

Inserção

Esta seção cobre os parâmetros que podem ser usados na inserção de novas linhas. Os parâmetros usados unicamente com a cláusula ON CONFLICT são descritos separadamente.

consulta_WITH

A cláusula WITH permite especificar uma ou mais subconsultas que podem ser referenciadas por nome no comando INSERT. Veja Consultas WITH (Expressões de tabela comuns) e SELECT para obter detalhes.

É possível que a consulta (instrução SELECT) também contenha uma cláusula WITH. Neste caso, os dois conjuntos de consulta_WITH podem ser referenciados dentro da consulta, mas o segundo tem precedência, uma vez que está mais próximo.

nome_da_tabela

O nome (opcionalmente qualificado pelo esquema) da tabela existente.

alias

Um nome substituto para o nome_da_tabela. Quando é fornecido um alias, este oculta completamente o nome real da tabela. É particularmente útil quando a cláusula ON CONFLICT DO UPDATE se refere a uma tabela chamada excluded, uma vez que de outra forma este nome seria utilizado para o nome da tabela especial que representa a linha proposta para inserção.

nome_da_coluna

O nome da coluna na tabela indicada por nome_da_tabela. O nome da coluna pode ser qualificado com um nome de subcampo, ou índice de matriz, se necessário. (A inserção em apenas alguns campos de uma coluna composta deixa os outros campos nulos.) Ao referenciar uma coluna na cláusula ON CONFLICT DO UPDATE, não deve ser incluído o nome da tabela na especificação da coluna de destino. Por exemplo, INSERT INTO nome_da_tabela ... ON CONFLICT DO UPDATE SET nome_da_tabela.nome_da_coluna = 1 não é válido (isto segue o comportamento geral para o comando UPDATE).

OVERRIDING SYSTEM VALUE

Se esta cláusula for especificada, quaisquer valores fornecidos para colunas de identidade substituirão os valores padrão gerados pela sequência.

Para uma coluna de identidade definida como GENERATED ALWAYS, é errado inserir um valor explícito (diferente de DEFAULT) sem especificar OVERRIDING SYSTEM VALUE ou OVERRIDING USER VALUE. (Para uma coluna de identidade definida como GENERATED BY DEFAULT, OVERRIDING SYSTEM VALUE é o comportamento normal, e especificá-lo não faz nada, mas o PostgreSQL permite isto como uma extensão.)

OVERRIDING USER VALUE

Se esta cláusula for especificada, quaisquer valores fornecidos para colunas de identidade serão ignorados, e os valores padrão gerados pela sequência serão aplicados.

Esta cláusula é útil, por exemplo, ao copiar valores entre tabelas. Escrever INSERT INTO tbl2 OVERRIDING USER VALUE SELECT * FROM tbl1 irá copiar todas as colunas de tbl1 que não são colunas de identidade em tbl2, enquanto os valores para as colunas de identidade em tbl2 serão gerados pelas sequências associadas a tbl2.

DEFAULT VALUES

Todas as colunas serão preenchidas com seus valores padrão, como se DEFAULT fosse explicitamente especificado para cada coluna. (A cláusula OVERRIDING não é permitida nesta forma.)

expressão

A expressão ou valor a ser atribuído à coluna correspondente.

DEFAULT

A coluna correspondente será preenchida com seu valor padrão. Uma coluna de identidade será preenchida com o novo valor gerado pela sequência associada. Para uma coluna gerada, é permitido especificar isto, mas apenas especifica o comportamento normal do cálculo da coluna a partir de sua expressão de geração.

consulta

Uma consulta (comando SELECT) que fornece as linhas a serem inseridas. Veja o comando SELECT para obter a descrição da sintaxe.

alias_da_saída

Um nome substituto opcional para as linhas OLD ou NEW na lista RETURNING.

Por padrão, os valores antigos da tabela de destino podem ser retornados escrevendo OLD.nome_da_coluna ou OLD.*, e novos valores podem ser retornados escrevendo NEW.nome_da_coluna ou NEW.*. Quando é fornecido um alias, estes nomes ficam ocultos e as linhas antigas ou novas devem ser referenciadas usando o alias. Por exemplo RETURNING WITH (OLD AS o, NEW AS n) o.*, n.*.

expressão_de_saída

Uma expressão a ser computada e retornada pelo comando INSERT, após cada linha ser inserida ou atualizada. A expressão pode usar qualquer nome de coluna da tabela indicada por nome_da_tabela. Deve ser escrito * para retornar todas as colunas inseridas ou atualizadas.

Um nome de coluna ou * pode ser qualificado usando OLD ou NEW, ou o alias_da_saída correspondente para OLD ou NEW, para que valores antigos ou novos sejam retornados. Um nome de coluna sem qualificação, ou *, ou um nome de coluna, ou * qualificado usando o nome ou alias da tabela de destino retornará os novos valores.

Para um comando INSERT simples, todos os valores antigos serão NULL. Entretanto, para um comando INSERT com uma cláusula ON CONFLICT DO UPDATE, os valores antigos podem não ser NULL.

nome_de_saída

O nome a ser usado para a coluna retornada.

Cláusula ON CONFLICT

A cláusula opcional ON CONFLICT especifica uma ação alternativa quando acontece um erro de violação de restrição de unicidade ou de exclusão. Para cada linha individual proposta para inserção, ou a inserção é feita, ou se uma restrição arbitral ou de índice especificada por conflito_alvo for violada, a ação_de_conflito alternativa será executada. A cláusula ON CONFLICT DO NOTHING simplesmente evita inserir a linha como sua ação alternativa. A cláusula ON CONFLICT DO UPDATE atualiza a linha existente, que entra em conflito com a linha proposta para inserção, como sua ação alternativa.

O parâmetro conflito_alvo pode realizar a inferência de índice de unicidade. A inferência consiste em especificar um ou mais nome_da_coluna_de_índice e/ou expressão_de_índice, e um predicado_de_índice. Todos os índices de unicidade em nome_da_tabela que, independentemente da ordem, contêm exatamente as colunas/expressões especificadas em conflito_alvo são inferidos (escolhidos) como índices árbitros. Se for especificado um predicado_de_índice, ele deve, como requisito adicional para inferência, satisfazer os índices árbitros. Note que isto significa que um índice de unicidade não parcial (um índice de unicidade sem predicado) será inferido (portanto, usado por ON CONFLICT), se este índice satisfazendo todos os outros critérios estiver disponível. Se a tentativa de inferência não for bem-sucedida, será relatado erro.

A cláusula ON CONFLICT DO UPDATE garante um resultado para INSERT ou UPDATE atômico; desde que não haja erro independente, um desses dois resultados é garantido, mesmo sob alta simultaneidade. Isto também é conhecido como UPSERTUPDATE ou INSERT.

conflito_alvo

Especifica para quais conflitos a cláusula ON CONFLICT assume a ação alternativa escolhendo os índices árbitros. Executa a inferência de índice de unicidade, ou indica uma restrição explicitamente. Para ON CONFLICT DO NOTHING, é opcional especificar conflito_alvo; quando omitido, os conflitos com todas as restrições utilizáveis (e índices de unicidade) são tratados. Para ON CONFLICT DO UPDATE, o conflito_alvo deve ser fornecido.

ação_de_conflito

O parâmetro ação_de_conflito especifica uma ação alternativa para ON CONFLICT. Pode ser tanto uma cláusula DO NOTHING, quanto DO UPDATE, especificando os detalhes exatos da ação UPDATE a ser executada em caso de conflito. As cláusulas SET e WHERE em ON CONFLICT DO UPDATE têm acesso à linha existente usando o nome da tabela (ou um alias), e para a linha proposta para inserção usando a tabela especial excluded. É necessário possuir o privilégio SELECT em qualquer coluna da tabela de destino onde as colunas da tabela excluded correspondentes serão lidas.

Note que os efeitos de todos os gatilhos BEFORE INSERT no nível de linha são refletidos nos valores da tabela excluded, porque estes efeitos podem ter contribuído para a linha ter sido excluída da inserção.

nome_da_coluna_de_índice

O nome da coluna de nome_da_tabela. Usado para inferir os índices árbitros. Segue o formato de CREATE INDEX. É requerido o privilégio SELECT em nome_da_coluna_de_índice.

expressão_de_índice

Semelhante a nome_da_coluna_de_índice, mas usado para inferir expressões em colunas de nome_da_tabela que aparecem dentro de definições de índice (não colunas simples). Segue o formato de CREATE INDEX. É requerido o privilégio SELECT em todas as colunas que aparecem na expressão_de_índice.

ordenação

Quando especificado, determina que o nome_da_coluna_de_índice ou expressão_de_índice correspondente use uma ordenação específica para ser correspondido durante a inferência. Normalmente é omitido, porque as ordenações geralmente não afetam se ocorre ou não uma violação de restrição. Segue o formato de CREATE INDEX.

classe_de_operador

Quando especificado, determina que o nome_da_coluna_de_índice ou expressão_de_índice correspondente use uma classe de operador específica para ser correspondido durante a inferência. Normalmente é omitido, porque a semântica de igualdade geralmente é equivalente nas classes de operador de um tipo de dados, ou porque é suficiente confiar que os índices de unicidade definidos tenham a definição pertinente de igualdade. Segue o formato de CREATE INDEX.

predicado_de_índice

Usado para permitir a inferência de índices de unicidade parciais. Quaisquer índices que satisfaçam o predicado (que, na verdade, não precisam ser índices parciais) podem ser inferidos. Segue o formato de CREATE INDEX. É requerido o privilégio SELECT em todas as colunas que aparecem no predicado_de_índice.

nome_da_restrição

Especifica explicitamente uma restrição árbitra pelo nome, em vez de inferir uma restrição pelo nome ou índice.

condição

Uma expressão que retorna um valor do tipo de dados boolean. Apenas as linhas para as quais esta expressão retorna true serão atualizadas, embora todas as linhas sejam bloqueadas quando a ação ON CONFLICT DO UPDATE for executada. Note que a condição é avaliada por último, após um conflito ter sido identificado como candidato a atualização.

Note que as restrições de exclusão não são suportadas como árbitros com ON CONFLICT DO UPDATE. Em todos os casos, apenas as restrições NOT DEFERRABLE, e índices de unicidade, têm suporte como árbitros.

O comando INSERT com a cláusula ON CONFLICT DO UPDATE é uma declaração determinística. Isto significa que o comando não poderá afetar nenhuma linha existente mais de uma vez; será relatado um erro de violação de cardinalidade quando esta situação surgir. As linhas propostas para inserção não devem duplicar umas às outras em termos de atributos restritos por um índice ou restrição árbitra.

Note que no momento não há suporte para a cláusula ON CONFLICT DO UPDATE de um comando INSERT, aplicado a uma tabela particionada, para atualizar a chave de partição de uma linha conflitante, exigindo que a linha seja movida para uma nova partição.

Dica

É geralmente preferível usar a inferência de índice de unicidade, em vez de indicar uma restrição diretamente usando ON CONFLICT ON CONSTRAINT nome_da_restrição. A inferência continuará a funcionar corretamente quando o índice subjacente for substituído por outro índice mais ou menos equivalente de forma sobreposta, por exemplo, ao usar CREATE UNIQUE INDEX ... CONCURRENTLY, antes de descartar o índice que está sendo substituído.

Atenção

Enquanto CREATE INDEX CONCURRENTLY ou REINDEX CONCURRENTLY estiver em execução em um índice de unicidade, os comandos INSERT ... ON CONFLICT na mesma tabela podem falhar de forma não esperada devido a uma violação de unicidade.

Saídas

Após a conclusão bem-sucedida, o comando INSERT retorna uma etiqueta de comando na forma

INSERT oid contador

O contador é o número de linhas inseridas ou atualizadas. O oid é sempre zero (costumava ser o OID atribuído à linha inserida se contador fosse exatamente igual a um, e a tabela de destino fosse declarada WITH OIDS, e zero caso contrário, mas criar uma tabela WITH OIDS não tem mais suporte).

Se o comando INSERT contiver uma cláusula RETURNING, o resultado será semelhante ao de um comando SELECT contendo as colunas e valores definidos na lista RETURNING, calculado sobre a(s) linha(s) inserida(s) ou atualizada(s) pelo comando.

Notas

Se a tabela especificada for uma tabela particionada, cada linha será roteada para a partição apropriada e inserida nela. Se a tabela especificada for uma partição, ocorrerá um erro se uma das linhas de entrada violar a restrição de partição.

Também pode ser considerado o uso do comando MERGE, já que este comando permite misturar INSERT, UPDATE e DELETE em uma única declaração. Veja MERGE.

Exemplos

Inserir uma única linha na tabela films:

INSERT INTO films VALUES
    ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');

Neste exemplo, a coluna len é omitida, portanto, receberá o valor padrão:

INSERT INTO films (code, title, did, date_prod, kind)
    VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');

Este exemplo usa a cláusula DEFAULT para as colunas de data em vez de especificar o valor:

INSERT INTO films VALUES
    ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes');
INSERT INTO films (code, title, did, date_prod, kind)
    VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama');

Para inserir uma linha que consiste inteiramente em valores padrão:

INSERT INTO films DEFAULT VALUES;

Para inserir várias linhas usando a sintaxe de VALUES de várias linhas:

INSERT INTO films (code, title, did, date_prod, kind) VALUES
    ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
    ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');

Este exemplo insere algumas linhas na tabela films a partir da tabela tmp_films, que tem a mesma disposição de colunas que a tabela films:

INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';

Este exemplo insere nas colunas da matriz:

-- Criar um tabuleiro de jogo 3x3 vazio para o jogo da velha
INSERT INTO tictactoe (game, board[1:3][1:3])
    VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}');
-- Os índices no exemplo acima não são realmente necessários
INSERT INTO tictactoe (game, board)
    VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');

Insira uma única linha na tabela distributors, retornando o número de sequência gerado pela cláusula DEFAULT:

INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets')
   RETURNING did;

Incrementar a contagem de vendas do vendedor que gerencia a conta da Acme Corporation, registrando todas as linhas atualizadas junto com a hora corrente em uma tabela de registro de transações:

WITH upd AS (
  UPDATE employees SET sales_count = sales_count + 1 WHERE id =
    (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')
    RETURNING *
)
INSERT INTO employees_log SELECT *, current_timestamp FROM upd;

Inserir ou atualizar novos distribuidores conforme apropriado. É assumido que foi definido um índice de unicidade que restringe os valores que aparecem na coluna did. Note que a tabela especial excluded é usada para referenciar os valores originalmente propostos para inserção:

INSERT INTO distributors (did, dname)
    VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
    ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;

Insira ou atualize novos distribuidores conforme descrito acima, retornando informações sobre quaisquer valores existentes que foram atualizados, juntamente com os novos dados inseridos. Note que os valores retornados para old_did e old_dname serão NULL para linhas sem conflito:

INSERT INTO distributors (did, dname)
    VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
    ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname
    RETURNING old.did AS old_did, old.dname AS old_dname,
              new.did AS new_did, new.dname AS new_dname;

Inserir um distribuidor, ou não fazer nada para as linhas propostas para inserção quando houver uma linha existente excluída (uma linha com uma restrição correspondentes em uma ou mais colunas após o disparo dos gatilhos para antes ou depois). Este exemplo assume que foi definido um índice de unicidade que restringe os valores que aparecem na coluna did:

INSERT INTO distributors (did, dname) VALUES (7, 'Redline GmbH')
    ON CONFLICT (did) DO NOTHING;

Inserir ou atualizar novos distribuidores conforme apropriado. Este exemplo assume que foi definido um índice de unicidade que restringe os valores que aparecem na coluna did. A cláusula WHERE é usada para limitar as linhas realmente atualizadas (qualquer linha existente não atualizada ainda será bloqueada, mesmo assim):

-- Não atualizar os distribuidores existentes com base em um determinado CEP
INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
    ON CONFLICT (did) DO UPDATE
    SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
    WHERE d.zipcode <> '21201';

-- Especificar a restrição diretamente na instrução
-- (usa o índice para arbitrar a ação de DO NOTHING)
INSERT INTO distributors (did, dname) VALUES (9, 'Antwerp Design')
    ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING;

Inserir um novo distribuidor se possível; senão DO NOTHING. Este exemplo assume que foi definido um índice de unicidade que restringe os valores que aparecem na coluna did em um subconjunto de linhas em que a coluna booleana is_active é avaliada como true :

-- Esta instrução pode inferir um índice de unicidade parcial em "did"
-- com o predicado de "WHERE is_active", mas também poderia usar apenas
-- uma restrição de unicidade regular em "did"
INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International')
    ON CONFLICT (did) WHERE is_active DO NOTHING;

Conformidade

O comando INSERT está em conformidade com o padrão SQL, exceto que a cláusula RETURNING é uma extensão PostgreSQL, assim como a capacidade de usar WITH com INSERT, e a capacidade de especificar uma ação alternativa com ON CONFLICT. Além disso, o caso em que a lista de nomes de colunas é omitida, mas nem todas as colunas são preenchidas a partir da cláusula VALUES ou consulta, não é permitido pelo padrão. Caso se prefira uma instrução que esteja mais em conformidade com o padrão SQL do que ON CONFLICT, veja MERGE.

O padrão SQL especifica que a cláusula OVERRIDING SYSTEM VALUE só pode ser especificado, se a coluna de identidade gerada sempre existe. O PostgreSQL permite a cláusula em qualquer caso, ignorando-a se não se aplicar.

As possíveis limitações da cláusula consulta estão documentadas no comando SELECT.