1
votes

Comment écrire une requête SQL multi-insert pour les tables primaires et secondaires

J'ai deux tables et je veux écrire une requête multi-insert de telle sorte que le PK de la première table soit automatiquement inséré en tant que fk dans une autre table.

Supposons les schémas de table suivants:

tblParent

INSERT INTO tblParent, tblChild (ParentValue, FkParentID, ChildValue) VALUES ('Parent 1', <ParentID of 'Parent 1'>, 'Child 1'), ('Parent 2', <ParentID of 'Parent 2'>, 'Child 2'), ('Parent 3', <ParentID of 'Parent 3'>, 'Child 3')

tblEnfant^

ChildID (Primary Key Auto increment)
FkParentID (Foreign Key)
ChildValue

Maintenant, je veux écrivez une requête multi-insert comme suit

ParentID (Primary Key Auto increment)
ParentValue

Mais je ne sais pas comment faire cela. J'ai des millions d'enregistrements à insérer dans ces tableaux. Et je ne veux pas insérer un enregistrement dans la première table, puis récupérer l'identifiant du parent et insérer des enregistrements dans la deuxième table.

Edit 1: Ma base de données est Mysql InnoDb

Edit 2: The les tables en question ont une relation un-à-plusieurs. Cela signifie donc que je veux effectuer une insertion dans tblParent et plusieurs insertions dans tblChild pour chaque enregistrement dans tblParent

Edit 3:

Je cherchais dans la documentation MySql et suis tombé sur la description suivante:

https: // dev .mysql.com / doc / refman / 8.0 / fr / information-functions.html # function_last-insert-id

L'instruction en cours d'exécution n'affecte pas la valeur de LAST_INSERT_ID (). Supposons que vous génériez une valeur AUTO_INCREMENT avec une instruction, puis que vous fassiez référence à LAST_INSERT_ID () dans une instruction INSERT à plusieurs lignes qui insère des lignes dans une table avec sa propre colonne AUTO_INCREMENT. La valeur de LAST_INSERT_ID () restera stable dans la deuxième instruction; sa valeur pour la deuxième ligne et les suivantes n'est pas affectée par les insertions de ligne précédentes. (Cependant, si vous mélangez des références à LAST_INSERT_ID () et LAST_INSERT_ID (expr), l'effet n'est pas défini.)

Ma prochaine question est donc, comment se comporterait LAST_INSERT_ID en cas d'insertion multiple pour tblParent qui à son tour a plusieurs insertions dans tblChild pour chaque tblParent


3 commentaires

Question similaire et réponse disponible sur ce message stackoverflow.com/questions/4775520/...


@Xun Merci pour la référence. Mon mauvais je n'ai pas pu chercher correctement. Je vais examiner cette question et la marquer comme double si les réponses qui y sont données sont satisfaisantes et conviennent à mon cas.


@Xun La façon dont ma question diffère de la question référencée est la suivante: je dois effectuer un-à-plusieurs dans ma table enfant, alors que la question référencée donne une réponse pour une relation un-à-un.


3 Réponses :


0
votes
<?php
//your codes

       $inset_tblParent= "INSERT INTO tblParent (ParentValue, FkParentID, ChildValue)VALUES('Parent 1', <ParentID of 'Parent 1'>, 'Child 1')";

     $inset_tblChild= "INSERT INTO tblChild (ParentValue, FkParentID, ChildValue)VALUES('Parent 2', <ParentID of 'Parent 2'>, 'Child 2')";


//your doces            
    ?>
you can able to use multiple insert like this.

2 commentaires

Dans tblParent FkParentID, ChildValue n'existe pas. Comment cela fonctionnerait-il?


vous utilisez if condition pour vérifier



0
votes

Vous pouvez insérer des données dans deux tableaux de la manière suivante: -

$result = INSERT INTO tblParent (ParentValue) VALUE('ABC');
if($result == true){
    $query = SELECT * tblParent ORDER BY ParentID DESC LIMIT 1;
    $row = $query->fetch_assoc();
    $ParentID = $row['ParentID'];
    INSERT INTO tblChild (FkParentID,ChildValue) VALUE('$ParentID','XYZ');
}


3 commentaires

Le problème est que je veux des insertions par lots, car j'ai des millions d'enregistrements à insérer. Je ne peux pas faire d'inserts individuels. Cela prendra beaucoup de temps. Et la solution que vous avez mentionnée est très inefficace pour mon cas d'utilisation.


Quelle table vous avez des millions d'enregistrement et quelle table vous voulez insérer des données?


La table parent aura des millions ou des enregistrements et l'enfant aura (nombre d'enregistrements dans Parent) * 10



0
votes

Quoi qu'il en soit, pour l'instant ce que j'ai fait est d'utiliser multi_query pour insérer des valeurs.

J'ai suivi dans une boucle while:

$autoIncForParent = <Max ID from tblParent>;
while(<condition to evaluate>) {
    if (!empty($multiQuery)) {
        $multiQuery .= ";";
    }
    $multiQuery .= "INSERT INTO tblParent (ParentID , ParentValue) VALUES ($autoIncForParent, 'Parent 1');";
    $multiQuery .= "INSERT INTO tblChild (FkParentID , ChildValue) VALUES ($autoIncForParent, 'Child 1');";
$autoIncForParent++;
}
$mysqli->multi_query($multiQuery);

Je suis presque sûr qu'il doit y avoir un autre bon moyen de résoudre ce problème.

J'ai pris en charge les problèmes de mémoire, les conditions de course et ce qui ne l'est pas dans mon code actuel. Cet extrait est uniquement à des fins d'élaboration. En aucun cas cet extrait de code est parfait et je ne le recommanderais pas pour la production.

Édition 1: Ajout de points-virgules manquants. Au cas où quelqu'un ferait référence à cela


0 commentaires