Comment insérer plusieurs valeurs dans une table postgres à la fois?

93

J'ai une table que j'essaye de mettre à jour plusieurs valeurs à la fois. Voici le schéma de la table:

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

J'ai le user_idet je veux insérer plusieurs subservice_idà la fois. Y a-t-il une syntaxe Postgresqui me permettra de faire quelque chose comme ça

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

Comment ferais-je cela?

jhamm
la source
1
Si vous souhaitez les insérer à partir d'une séquence, ou en utilisant generate_seriesvoir dba.stackexchange.com/a/89544/16892
rogerdpack

Réponses:

172

La syntaxe d'insertion à valeurs multiples est:

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

Mais la réponse de Krokodilko est beaucoup plus astucieuse.

Scott Marlowe
la source
Avec l'une ou l'autre de ces méthodes, existe-t-il un moyen de renvoyer également le id?
dvtan
2
Oui, utilisez le retour. "insérer dans la table (id, yada) les valeurs (1,2), (9,22) renvoyant l'id;" etc
Scott Marlowe
1
De plus, de nos jours, une instruction CTE aka WITH fonctionne souvent bien.
Scott Marlowe
Les valeurs entières peuvent être insérées comme ci-dessus. Mais lors de l'insertion de texte en utilisant la méthode ci-dessus, l'erreur d'obtention comme la colonne n'existe pas. 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, vous devrez utiliser des guillemets simples ' 'pour le texte que vous insérez. donc quelque chose comme, insert into orders_cancel_reasons_infos values (1,1,'Changed my mind',1), (2,2,'Quality not satisfactory',1)fonctionnera. Vous pouvez vérifier cela pour plus d'informations sur les guillemets simples et doubles.
dr0pdb
25

Une version plus courte de la réponse de Krokodilko:

insert into user_subservices(user_id, subservice_id) 
values(1, unnest(array[1, 2, 3]));
yallie
la source
Je pense que c'est plus expressif de l'intention que la réponse acceptée. Est-ce que ce standard SQL ou PostgreSQL est spécifique?
Bernard
3
Les deux réponses sont spécifiques à PostgreSQL. La réponse est peut - être acceptée plus facilement à d' autres bases de données traduit, Oracle par exemple: insert into user_subservices(user_id, subservice_id) select 1, column_value from table(sys.odcinumberlist(1,2,3)).
yallie
Merci, cela a beaucoup plus de sens et est plus lisible que la réponse acceptée à mon avis.
frosty
1
Une façon d'utiliser cela avec des informations d'une autre table: insert into user_subservices(user_id, subservice_id) values(1, unnest(ARRAY(select id from subservices where name like '%test%')));
Efren
12

Une réponse un peu liée car je n'arrête pas de trouver cette question à chaque fois que j'essaye de me souvenir de cette solution. Insérez plusieurs lignes avec plusieurs colonnes :

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

Exemple plus robuste, lorsque vous devez insérer plusieurs lignes dans une table pour chaque ligne d'une autre table:

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
la source