web-dev-qa-db-fra.com

MySQL Insérer dans plusieurs tables? (Normalisation de la base de données?)

J'ai essayé de rechercher un moyen de insert informations dans plusieurs tables de la même requête, mais j'ai découvert que c'était impossible? Je veux donc insert simplement en utilisant plusieurs requêtes i.e;

INSERT INTO users (username, password) VALUES('test', 'test')
INSERT INTO profiles (userid, bio, homepage) VALUES('[id of the user here?]','Hello world!', 'http://www.stackoverflow.com')

Mais comment puis-je donner l'incrémentation automatique id de users au "manuel" userid pour la table profile?

118
Jay Wit

Non, vous ne pouvez pas insérer plusieurs tables dans une seule commande MySQL. Vous pouvez cependant utiliser des transactions.

BEGIN;
INSERT INTO users (username, password)
  VALUES('test', 'test');
INSERT INTO profiles (userid, bio, homepage) 
  VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com');
COMMIT;

Examinez LAST_INSERT_ID() pour réutiliser les valeurs d'auto-incrémentation.

Edit: vous avez dit " Après tout ce temps en essayant de le comprendre, cela ne fonctionne toujours pas. Je ne peux pas simplement mettre l'ID généré dans un $ var et mettre ce $ var en tout les commandes MySQL? "

Permettez-moi de préciser: il y a 3 façons possibles ici:

  1. Dans le code que vous voyez ci-dessus. Tout cela est fait dans MySQL, et LAST_INSERT_ID() dans la deuxième instruction sera automatiquement la valeur de la colonne autoincrement-column insérée dans la première instruction.

    Malheureusement, lorsque la deuxième instruction insère elle-même des lignes dans une table avec une colonne à incrémentation automatique, la LAST_INSERT_ID() sera mise à jour pour correspondre à celle de la table 2 et non à celle de la table 1. Si vous avez toujours besoin de celle de la table 1, nous devrons enregistrer dans une variable. Cela nous amène aux moyens 2 et 3:

  2. Stockera la LAST_INSERT_ID() dans une variable MySQL:

    INSERT ...
    SELECT LAST_INSERT_ID() INTO @mysql_variable_here;
    INSERT INTO table2 (@mysql_variable_here, ...);
    INSERT INTO table3 (@mysql_variable_here, ...);
    
  3. Stockera la LAST_INSERT_ID() dans une variable php (ou toute langue pouvant se connecter à une base de données de votre choix):

    • INSERT ...
    • Utilisez votre langue pour récupérer la LAST_INSERT_ID(), soit en exécutant cette instruction littérale dans MySQL, soit en utilisant, par exemple, la mysql_insert_id() de php qui le fait pour vous.
    • INSERT [use your php variable here]

ATTENTION

Quelle que soit la solution choisie, vous devez décider de ce qui doit se passer si l'exécution devait être interrompue entre des requêtes (par exemple, votre serveur de base de données se bloque). Si vous pouvez vivre avec "certains ont fini, d'autres pas", ne lisez pas.

Si toutefois vous décidez "toutes les requêtes sont terminées ou aucune ne se termine - je ne veux pas de lignes dans certaines tables, mais pas de lignes correspondantes dans d'autres, je veux toujours que mes tables de base de données soient cohérentes", vous devez envelopper toutes les instructions dans une transaction. C'est pourquoi j'ai utilisé le BEGIN et COMMIT ici.

Commente encore si tu as besoin de plus d'infos :)

214
Konerak

assez simple si vous utilisez des procédures stockées:

call insert_user_and_profile('f00','http://www.f00.com');

script complet:

drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varchar(32) unique not null
)
engine=innodb;

drop table if exists user_profile;
create table user_profile
(
profile_id int unsigned not null auto_increment primary key,
user_id int unsigned not null,
homepage varchar(255) not null,
key (user_id)
)
engine=innodb;

drop procedure if exists insert_user_and_profile;

delimiter #

create procedure insert_user_and_profile
(
in p_username varchar(32),
in p_homepage varchar(255)
)
begin
declare v_user_id int unsigned default 0;

insert into users (username) values (p_username);
set v_user_id = last_insert_id(); -- save the newly created user_id

insert into user_profile (user_id, homepage) values (v_user_id, p_homepage);

end#

delimiter ;

call insert_user_and_profile('f00','http://www.f00.com');

select * from users;
select * from user_profile;
15
Jon Black

Que se passerait-il si vous souhaitiez créer de nombreux enregistrements de ce type (pour enregistrer 10 utilisateurs, pas un seul)? Je trouve la solution suivante (seulement 5 interrogations):

Étape I: Créer une table temporaire pour stocker de nouvelles données.

CREATE TEMPORARY TABLE tmp (id bigint(20) NOT NULL, ...)...;

Ensuite, remplissez ce tableau avec des valeurs.

INSERT INTO tmp (username, password, bio, homepage) VALUES $ALL_VAL

Ici, au lieu de $ALL_VAL, vous placez une liste de valeurs: ('test1', 'test1', 'bio1', 'home1'), ..., ('testn', 'testn', 'bion', 'homen')

Étape II: Envoyer les données à la table 'utilisateur'.

INSERT IGNORE INTO users (username, password)
SELECT username, password FROM tmp;

Ici, "IGNORE" peut être utilisé si vous autorisez déjà certains utilisateurs à être à l'intérieur. Vous pouvez également utiliser UPDATE comme avant l’étape III, avant cette étape, pour rechercher les utilisateurs déjà présents (et les marquer dans la table tmp). Ici, nous supposons que ce nom d'utilisateur est déclaré en tant que PRIMARY dans la table users.

Étape III: Appliquer la mise à jour pour lire tous les identifiants d’utilisateurs d’utilisateurs dans la table tmp.CETTE IS ÉTAPE ESSENTIELLE.

UPDATE tmp JOIN users ON tmp.username=users.username SET tmp.id=users.id

Étape IV: Créer une autre table, en utilisant read id pour les utilisateurs

INSERT INTO profiles (userid, bio, homepage) 
SELECT id, bio, homepage FROM tmp
4
Zasega Anonimno

essaye ça 

$sql= " INSERT INTO users (username, password) VALUES('test', 'test') ";
mysql_query($sql);
$user_id= mysql_insert_id();
if(!empty($user_id) {

$sql=INSERT INTO profiles (userid, bio, homepage) VALUES($user_id,'Hello world!', 'http://www.stackoverflow.com');
/* or 
 $sql=INSERT INTO profiles (userid, bio, homepage) VALUES(LAST_INSERT_ID(),'Hello   world!', 'http://www.stackoverflow.com'); */
 mysql_query($sql);
};

Références
PHP
MYSQL

3
diEcho

jetez un oeil à mysql_insert_id ()

ici la documentation: http://in.php.net/manual/en/function.mysql-insert-id.php

2
Daniel Kutik

C’est ce que j’ai fait dans le cadre d’un projet universitaire, tout fonctionne bien, sans doute pas sûr

$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = '';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);

$title =    $_POST['title'];            
$name =     $_POST['name'];         
$surname =  $_POST['surname'];                  
$email =    $_POST['email'];            
$pass =     $_POST['password'];     
$cpass =    $_POST['cpassword'];        

$check = 1;

if (){
}
else{
    $check = 1;
}   
if ($check == 1){

require_once('website_data_collecting/db.php');

$sel_user = "SELECT * FROM users WHERE user_email='$email'";
$run_user = mysqli_query($con, $sel_user);
$check_user = mysqli_num_rows($run_user);

if ($check_user > 0){
    echo    '<div style="margin: 0 0 10px 20px;">Email already exists!</br>
             <a href="recover.php">Recover Password</a></div>';
}
else{
    $users_tb = "INSERT INTO users ". 
           "(user_name, user_email, user_password) ". 
        "VALUES('$name','$email','$pass')";

    $users_info_tb = "INSERT INTO users_info".
           "(user_title, user_surname)".
        "VALUES('$title', '$surname')";

    mysql_select_db('dropbox');
    $run_users_tb = mysql_query( $users_tb, $conn );
    $run_users_info_tb = mysql_query( $users_info_tb, $conn );

    if(!$run_users_tb || !$run_users_info_tb){
        die('Could not enter data: ' . mysql_error());
    }
    else{
        echo "Entered data successfully\n";
    }

    mysql_close($conn);
}

}

0
SebastianZdroana