Para um banco de dados de teste, gostaria de criar vários usuários de teste (todos com valores "padrão"). Há uma tabela chamada users
, e outra chamada user_properties
. Para cada usuário de teste, preciso fazer entradas correspondentes em ambas as tabelas. Eu já tenho um CTE funcionando bem para fazer isso, mas não consigo envolver esse CTE em um loop.
CREATE OR REPLACE FUNCTION ins()
returns void as
$BODY$
BEGIN
--RETURN record;
FOR Loopid IN 0..10 LOOP
with
user as (
insert into user
values(default)
returning id
)
,user_property as (
insert into user_property (property_of)
select id from user
returning id
)
select id from user_property;
END LOOP;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Ele cria a função, mas ao executar reclama
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
Mas não parece possível substituir o último select
CTE por um perform
- isso é um erro de sintaxe. Então, como posso fazer isso?
As estruturas da tabela podem ser consideradas muito simples, pois a maioria das colunas terá os valores padrão. A tabela user
tem uma única coluna id
e user_properties
tem duas colunas id
e property_of
- que é uma chave estrangeira para col id
na user
tabela. Ambas as id
colunas são sequências geradas automaticamente.
As poucas perguntas ( exemplo ) que têm títulos muito semelhantes têm a resposta de que um loop/cte não é realmente necessário, então elas não me ajudam.
Primeiro:
user
é uma palavra-chave reservada, você precisa usar aspas duplas se quiser usá-la como nome de tabela:"user"
Mas sugiro fortemente que você encontre um nome diferente.Para responder sua pergunta imediata: basta remover a seleção final do CTE - essa é a causa do erro (já que você precisa armazenar o resultado dessa seleção em algum lugar).
Observe que o nome do idioma é um identificador, você não deve colocá-lo entre aspas simples.
No entanto, você realmente não precisa de uma função para isso: