Como faço para inserir vários valores em uma tabela postgres de uma vez?

91

Tenho uma tabela que estou tentando atualizar vários valores de uma vez. Aqui está o esquema da tabela:

    Column     |  Type   | Modifiers 
---------------+---------+-----------
 user_id       | integer | 
 subservice_id | integer |

Eu tenho o user_ide desejo inserir vários de subservice_iduma vez. Existe uma sintaxe Postgresque me permita fazer algo assim

insert into user_subservices(user_id, subservice_id) values(1, [1, 2, 3]);

Como eu faria isso?

Jhamm
fonte
1
Se você quiser inseri-los de uma sequência ou usando, generate_seriesconsulte dba.stackexchange.com/a/89544/16892
rogerdpack

Respostas:

170

A sintaxe de inserção de vários valores é:

insert into table values (1,1), (1,2), (1,3), (2,1);

Mas a resposta de krokodilko é muito mais engenhosa.

Scott Marlowe
fonte
Com qualquer um desses métodos, há uma maneira de retornar também o id?
dvtan
2
Sim, use o retorno. "insira na tabela (id, yada) valores (1,2), (9,22) retornando id;" etc
Scott Marlowe
1
Também hoje em dia uma instrução CTE também conhecida como WITH geralmente funciona bem.
Scott Marlowe
Os valores inteiros podem ser inseridos como acima. Mas ao inserir texto usando o método acima, ele obtém um erro como se a coluna não existisse. insert into orders_cancel_reasons_infos values (1,1,"Changed my mind",1), (2,2,"Quality not satisfactory",1), (3,3,"Incompatible or not useful",1), (4,4,"Damaged product but shipping box is good",1), (5,5,"Items arrived too late",1), (6,6,"Missing part or accessories",1), (7,7,"Product and shipping box are damaged",1), (8,8,"Wrong item was sent",1), (9,9,"Defective item",1), (10,10,"Inaccurate description",1), (11,11,"Other",1);
sankar muniyappa
@sankarmuniyappa você terá que usar aspas simples ' 'para o texto que está inserindo. então algo como, insert into orders_cancel_reasons_infos values (1,1,'Changed my mind',1), (2,2,'Quality not satisfactory',1)vai funcionar. Você pode verificar isso para obter mais informações sobre aspas simples e duplas.
dr0pdb
24

Uma versão mais curta da resposta de krokodilko:

insert into user_subservices(user_id, subservice_id) 
values(1, unnest(array[1, 2, 3]));
yallie
fonte
Acho que isso é mais expressivo de intenção do que a resposta aceita. Este padrão é SQL ou específico do PostgreSQL?
Bernard
3
Ambas as respostas são específicas do PostgreSQL. A resposta aceita é talvez mais facilmente traduzidas para outros bancos de dados, a Oracle por exemplo: insert into user_subservices(user_id, subservice_id) select 1, column_value from table(sys.odcinumberlist(1,2,3)).
yallie
Obrigado, isso faz muito mais sentido e é mais legível do que a resposta aceita em minha opinião.
gelado de
1
Uma forma de usar isso com as informações de outra tabela: insert into user_subservices(user_id, subservice_id) values(1, unnest(ARRAY(select id from subservices where name like '%test%')));
Efren
11

Uma resposta ligeiramente relacionada, porque continuo encontrando essa pergunta toda vez que tento me lembrar dessa solução. Insira várias linhas com várias colunas :

insert into user_subservices (user_id, subservice_id)
select *
from unnest(array[1, 2], array[3, 4]);
Andreas Hultgren
fonte
2

Exemplo mais robusto, para quando você precisar inserir várias linhas em alguma tabela para cada linha em outra tabela:

INSERT INTO user_subservices (user_id, subservice_id)
SELECT users.id AS user_id, subservice_id
FROM users
CROSS JOIN unnest(ARRAY[1,2,3]) subservice_id;
Envek
fonte