Estou tentando gerar tabelas fictícias com dados fictícios para testar o desempenho com algumas tarefas SQL.
Com base neste tópico antigo: Existe uma maneira de inserir várias linhas em uma tabela com valores padrão para todas as colunas?
Percebi que com um IDENTITY
tipo, não é mais possível preencher uma tabela com dados fictícios usando a generate_series(1, N)
solução sugerida.
Então, como eu poderia inserir 1.000 dados fictícios, por exemplo, na tabela a seguir (PG 14), aproveitando o valor padrão para o campo name
sem substituir os valores do sistema para o campo id
:
CREATE TABLE foo (
id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
name TEXT DEFAULT md5(random()::text)
);
Tentar o seguinte falha:
INSERT INTO foo (id)
SELECT generate_series(1, 1000);
-- which results in:
ERROR: cannot insert a non-DEFAULT value into column "id"
DETAIL: Column "id" is an identity column defined as GENERATED ALWAYS.
HINT: Use OVERRIDING SYSTEM VALUE to override.
SQL state: 428C9
Como solução alternativa, agora estou criando a tabela com um campo extra i
tão simples INTEGER
para alimentar este em vez do id
e soltá-lo após a inserção dos dados, mas não é 100% limpo para mim.
Eu estava esperando por algo simples e claro como isso, por exemplo:
INSERT INTO foo DEFAULT VALUES (1000);
mas esta é obviamente uma sintaxe inválida.
Outro método que pode ser usado mesmo quando todas as colunas possuem expressões padrão é fornecer uma coluna e usar a
OVERRIDING USER VALUE
opção noINSERT
para ignorar esses valores fornecidos.Testado em dbfiddle.uk (1)
Mais um método que usa
MERGE
- disponível apenas na versão 15 do Postgres (a ser lançada no próximo mês). Obrigado a Paul White que localizou as perguntas semelhantes para SQL Server e Martin Smith e AndriyM pelas respostas:IDENTITY
colunaReescrito aqui com as mudanças necessárias para o Postgres e testado em dbfiddle.uk (2) :
(Nota de desejo atualizada)
Seria bom se pudéssemos fornecer uma tabela de 0 colunas como entrada, mas isso ainda não foi implementado - o
select
funciona por conta própria, mas não oinsert into foo ()
:Mas isso funciona desde a versão 9.4. O truque é usar
insert into foo
- sem o()
- que aceita uma tabela de entrada com número arbitrário de colunas (de zero até o número de colunas da tabela):Testando todos os três métodos em dbfiddle.uk (3) :
alternativamente
violino