Maison >base de données >tutoriel mysql >Comment insérer des données dans plusieurs tables Postgres associées en une seule requête ?

Comment insérer des données dans plusieurs tables Postgres associées en une seule requête ?

DDD
DDDoriginal
2025-01-12 14:50:41139parcourir

How to Insert Data into Multiple Related Postgres Tables in a Single Query?

Insertion de données à requête unique sur plusieurs tables Postgres associées

Ce guide aborde le défi de l'insertion de données dans plusieurs tables Postgres interconnectées à l'aide d'une seule requête SQL, en particulier lorsqu'il est nécessaire de récupérer une clé primaire à partir d'une insertion initiale et de l'utiliser comme clé étrangère dans des insertions ultérieures.

Le problème : Insérer efficacement des données dans trois tables liées ou plus au sein d'une seule requête, en garantissant le maintien des relations de clé étrangère appropriées.

Solution : tirer parti des CTE modifiant les données

Les expressions de table communes (CTE) offrent une solution élégante. Les CTE de modification de données permettent des opérations INSERT séquentielles, où chaque insertion ultérieure repose sur les résultats de la précédente.

Exemple de mise en œuvre :

Ce qui suit montre l'insertion de données dans trois tables (sample, sample1, sample2) à l'aide de CTE de modification de données :

<code class="language-sql">WITH ins1 AS (
   INSERT INTO sample(firstname, lastname)
   VALUES ('fai55', 'shaggk')
   RETURNING id AS sample_id
   ),
ins2 AS (
   INSERT INTO sample1 (sample_id, adddetails)
   SELECT sample_id, 'ss' FROM ins1
   RETURNING user_id
   )
INSERT INTO sample2 (user_id, value)
SELECT user_id, 'ss2' FROM ins2;</code>

Explication :

  1. ins1 : insère une ligne dans la table sample et renvoie le id (clé primaire) nouvellement généré sous la forme sample_id.
  2. ins2 : utilise le sample_id de ins1 pour insérer une ligne dans sample1, renvoyant le user_id généré.
  3. Final INSERT : utilise le user_id de ins2 pour insérer des données dans sample2.

Alternative : Insertion par lots avec CTE

Cette approche gère plusieurs lignes de données simultanément :

<code class="language-sql">WITH data(firstname, lastname, adddetails, value) AS (
   VALUES
      ('fai55', 'shaggk', 'ss', 'ss2'),
      ('fai56', 'XXaggk', 'xx', 'xx2')
   ),
ins1 AS (
   INSERT INTO sample (firstname, lastname)
   SELECT firstname, lastname FROM data
   RETURNING firstname, lastname, id AS sample_id
   ),
ins2 AS (
   INSERT INTO sample1 (sample_id, adddetails)
   SELECT ins1.sample_id, d.adddetails
   FROM   data d
   JOIN   ins1 USING (firstname, lastname)
   RETURNING sample_id, user_id
   )
INSERT INTO sample2 (user_id, value)
SELECT ins2.user_id, d.value
FROM   data d
JOIN   ins1 USING (firstname, lastname)
JOIN   ins2 USING (sample_id);</code>

Cela insère efficacement plusieurs lignes en les définissant dans le data CTE.

Considérations importantes :

  • Contraintes de clé étrangère : Assurez-vous que les contraintes de clé étrangère appropriées sont définies pour maintenir l'intégrité référentielle.
  • Clause ON CONFLIT : Utilisez ON CONFLICT pour gérer les erreurs potentielles de clé en double.
  • Concurrence : Soyez conscient des conditions de concurrence potentielles lors des écritures de données simultanées.

Cette approche globale fournit une méthode robuste et efficace pour gérer l'insertion de données dans les tables Postgres associées au sein d'une seule requête.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn