[SQL] 2 Insert en 1 -> Problème

2 Insert en 1 -> Problème [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 08-12-2004 à 13:03:17    

Bonjour à tous,
 
Voilà j'ai un petit problème, j'aimerais ajouter deux records dans deux tables différentes en une seule requete.
 
Mes tables :
[table1]
id    [int auto-increment]
nom   [varchar 50]
 
[table2]
id        [int auto-increment]
nomembre  [int]
 
Le problème que j'ai est comment récupérer le id.table1 qui est un numéro automatique pour le mettre dans nomembre.table2 ?
 
Sans cela la requête n'a rien de compliqué mais là je bloque et je ne trouve pas sur internet.
 
Quelqu'un a-t-il la réponse ?
 
D'avance merci !
Laurent


Message édité par imnotgood le 08-12-2004 à 13:26:51
Reply

Marsh Posté le 08-12-2004 à 13:03:17   

Reply

Marsh Posté le 08-12-2004 à 13:33:49    

Tu peux toujours insérer 'select (max(id) + 1) from table1', non?(en considérant que le pas est 1)...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-12-2004 à 13:38:17    

Salut,
 
J'y avais pensé mais dans le cas ou je supprime le dernier record de la table1 car le topic n'est pas conforme ben ça risque de partir en sucette...
 
Exemple :
[table1]
1  test
2  demo
3  blabla  <-- record que je supprime
 
Le prochain enregistrement dans la table aura l'id 4 (à cause de l'auto increment) et donc au prochain ajout, dans table1 l'id vaudra 4 alors que nomembre de table2 vaudra 3
 
:'(
 
Merci quand même...
Laurent

Reply

Marsh Posté le 08-12-2004 à 13:40:17    

Alors je vois pas comment faire ça en une seule requête...tu as besoin de connaitre un nombre qui n'existe pas encore...[:skeye]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-12-2004 à 13:43:38    

Il n'y a pas un moyen de savoir quel est l'id qui sera généré ou le dernier qui a été généré ? (excepté max() qui donne la plus grande valeur)
 
:(
D'avance merci.
Laurent
 
ps: base de données mysql mais je ne pense pas qu'il y ait une fonction qui lui soit spécifique. Je vais encore chercher de mon coté et si je trouve je poste ;)

Reply

Marsh Posté le 08-12-2004 à 13:46:11    

Si, ce genre de choses est assez spécifique au SGBD...
 
J'ai trouvé la fonction LAST_INSERT_ID(), pour mysql...ça devrait suffire à tes besoins, non?
 
http://dev.mysql.com/doc/mysql/en/ [...] EMENT.html


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-12-2004 à 13:46:39    

SELECT LAST_INSERT_ID()
 
Je vais tester et je pense que ce sera bon :D
 
Laurent

Reply

Marsh Posté le 08-12-2004 à 13:47:03    

arf t'as été plus rapide ;)
 
Laurent

Reply

Marsh Posté le 08-12-2004 à 13:49:33    

skeye a écrit :

Tu peux toujours insérer 'select (max(id) + 1) from table1', non?(en considérant que le pas est 1)...


A éviter !  :non:


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 08-12-2004 à 13:50:59    

Ben c'est bien pour ça qu'on a continué à chercher ;)
 
Skeye merci bcp en tout cas...
Je te tiens au courrant d'ici 10 min
 
Laurent

Reply

Marsh Posté le 08-12-2004 à 13:50:59   

Reply

Marsh Posté le 08-12-2004 à 13:55:38    

sircam a écrit :

A éviter !  :non:


(c'était une solution 'par défaut'...)


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-12-2004 à 14:00:24    

skeye a écrit :

Tu peux toujours insérer 'select (max(id) + 1) from table1', non?(en considérant que le pas est 1)...


Et t'en fait quoi des connections concommittantes dans ce cas ?
Non, hors de question de faire un max+1, au boulot, y'en a un qui me fait ça, c'est direct dans le bureau du directeur informatique : hors de question que je bosse sur un des projets auxquels il a touché.
 
Selon les SGBD, il y a différentes méthodes pour récupérer la dernière valeur de l'autoincrément, et ce, en respectant le scope de ta procédure : ainsi, même s'il se produit 100 inserts dans la même milliseconde dans la table, tu est SÛR ET CERTAIN que ton ID est celui que tu as utilisé pour l'insert, et qu'en aucun cas une autre requête ne risque de le reprendre.
 
Le max+1, t'es obligé de faire un select AVANT le insert pour pouvoir le stocker. Entre ce moment et l'insert, tu n'es pas à l'abris qu'une autre procédure fasse le même select sur les mêmes données, et va donc ensuite planter en insérant la même valeur pour l'ID.
Le genre de bug impossible à reproduire, et qu'on met des semaines à isoler.
 
imnotgood > Pour le "LAST_INSERT_ID()" fait gaffe que tu n'utilises pas des connections persistantes, sinon tu risques d'avoir le problème dont j'ai parlé ci-dessus.
 
Je tiens d'ailleurs à remercier l'abruti qui à mis à jour la page d'aide de "mysql_insert_id" sur le site php.net en août dernier, car il n'y a plus cet avertissement, alors que d'un point de vue purement technique, il est toujours présent. (mysql_insert_id ne fait rien d'autre que de récupérer la valeur de LAST_INSERT_ID())

Reply

Marsh Posté le 08-12-2004 à 14:03:01    

Je me demandais quand t'allais te pointer pour m'engueuler, toi...[:rofl]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-12-2004 à 14:04:25    

Ben j'étais parti manger [:spamafote]
 
Promis, le prochain coup je serai plus rapide :p


Message édité par Arjuna le 08-12-2004 à 14:04:33
Reply

Marsh Posté le 08-12-2004 à 14:10:02    

Lol...
 
Merci bcp à vous deux.
>imnotgood > Pour le "LAST_INSERT_ID()" fait gaffe que tu n'utilises pas des connections persistantes, sinon tu risques d'avoir le problème dont j'ai parlé ci-dessus.  
Non je n'en utilise pas, je n'en ai pas encore eu l'utilité à vrai dire...
 
Merci bcp !!
 
Laurent

Reply

Marsh Posté le 08-12-2004 à 16:11:48    

dsl erreur de ma part, je ne voulais pas poster ce msg ci...


Message édité par imnotgood le 08-12-2004 à 17:15:18
Reply

Marsh Posté le 09-12-2004 à 00:33:47    

qu'appel tu un scope de la procedure ??? (juste pour infos)

Reply

Marsh Posté le 09-12-2004 à 14:18:46    

C'est comme dans un programme :
Si tu déclares une variable en global, son scope c'est tout le programme : si tu la modifies, elle va impacter l'ensemble du programme.
Et si elle est déclarée à l'intérieur d'une fonction, son scope c'est la fonction et les appels de la fonction : si tu la modifies, seule la fonction et celles appelées par cette dernière seront impactées.
 
En SQL, t'as la même chose.
 
Le scope le plus grand, c'est la base. Ca veut dire que si une requête exécutée dans la base en dehors de ton programme modifie des données à l'extérieur de ton traîtement, tu vas être impacté par cette modif.
Ensuite, il y a le scope de la session : seules les requêtes éxécutée dans ta session vont impacter tes traîtements.
Il y a ensuite le scope de la transaction : tout ce qui est fait en dehors de ta transaction est ignoré par ta transaction.
Et enfin le scope de ton batch, où seules les requêtes qui sont dans ton batch peuvent influencer sur les requêtes de ton batch.
 
Le scope, c'est en fait un cloisonnement des actions dans la base.
Il n'y a pas de mot-clé permettant de forcer le scope de tes requêtes. Par contre, en utilisant différents types de transactions, etc. tu peux forcer le scope à un domaine bien défini.
 
En plus de ça, au niveau de la base, il y a généralement des fonctions qui filtrent le scope.
 
Par exemple, avec SQL Server, il y a 3 façon d'obtenir proprement le dernier auto-incrément. Je ne me souvient plus des nom mais bon :D
- Une variable système (commence par "@@" ). Son scope c'est la base entière : toute insersion dans n'importe quelle table va modifier sa valeure, quelquesoit la connection/transaction utilisée.
- Une première fonction dont le scope est la transaction. Si dans une même transaction tu fait plusieurs insert, elle contient la dernière valeur générée. Par contre, imagine que sur la table où tu fais le insert déclenche un trigger, qui lui-même re-crée une ligne, tu récupères l'ID de cette ligne crée par le trigger.
- Une dernière fonction dont le scope est l'instruction elle-même : même si un trigger sur ton insert crée des lignes, c'est l'ID de la ligne que tu as créé avec ton instruction insert qui est retourné.
 
Si t'as du mal à assimiler, demande-moi, je te poste les articles de l'aide MS SQL Server ce soir (là j'ai pas l'aide sur mon poste). Même si c'est la doc MS, ne tinquiète pas, c'est valable pour toutes les bases de données (le mode de fonctionnement du moins, le nom des variables et les fonctions peut différer ;))

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed