équivalent standard SQL de LAST_INSERT_ID ?

équivalent standard SQL de LAST_INSERT_ID ? - SQL/NoSQL - Programmation

Marsh Posté le 23-07-2007 à 14:41:13    

Bonjour,
 
j'ai une requete où je dois récupérer le dernier champ auto incrémenté d'une table pour insérer une ligne comportant cet ID dans une autre table.
Je l'ai fait avec la fonction LAST_INSERT_ID. Le probleme c'est qu'apparemment cette fonction est propre a MySQL.
 
Mon application doit être portable. Elle doit pouvoir marcher avec une base SQLite, qui n'accepte pas cette fonction.
Y a-t-il une méthode pour faire ca en standard SQL?
 
Merci pour votre aide.


Message édité par welcominh le 23-07-2007 à 14:41:59

---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 23-07-2007 à 14:41:13   

Reply

Marsh Posté le 23-07-2007 à 14:44:02    

je propose un simple
 
select max(auto_number_id) from table;

Reply

Marsh Posté le 23-07-2007 à 14:52:52    

Ce serait ok s'il n'y avait qu'un seul utilisateur à la fois. Mais l'application peut être utilisée par plusieurs personnes en même temps. Donc s'il y a un insert entre mon insertion et la requete qui récupère le max de l'ID, la valeur récupérée sera faussée  :sweat:
 
(désolé de ne pas l'avoir précisé plus tot)

Message cité 2 fois
Message édité par welcominh le 23-07-2007 à 14:53:24

---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 23-07-2007 à 15:05:02    

d'une manière générale l'exécution d'une requete ne remonte que le résultat à l'instant d'exécution, après tu peux créer une interface qui te donne en temps réel le dernier élément en cours... mais tu peux difficilement éliminée le risque d'ajout entre deux étapes...


Message édité par jpcheck le 23-07-2007 à 15:05:50
Reply

Marsh Posté le 23-07-2007 à 15:10:15    

Justement si la requete de récupération de l'ID max s'exécute apres une 2e insertion sur la table, je n'aurai pas le bon ID. Je vois toujours pas comment faire.
 
EDIT: donc pas de solution fiable a priori ?


Message édité par welcominh le 23-07-2007 à 15:11:19

---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 23-07-2007 à 15:12:05    

peut être en faisant deux requetes une au debut, une apres, juste avant ton insertion dans ton autre table...

Reply

Marsh Posté le 23-07-2007 à 15:32:33    

Je n'ai pas parfaitement saisi ta phrase. Mais si tu parles de récupérer l'id_max avant l'insertion dans la 1ere table, puis de re-récupérer l'id_max sur cette 1ere table afin de comparer si id_max_apres= id_max_avant+1, ca pose la question du nombres de lignes insérées entre ces 2 étapes. Le probleme n'est que reporté. La possibilité d'avoir des insertions mulitples entre ces 2 étapes est d'autant plus faible, mais je n'aime pas l'idée du "ca marche la plupart du temps donc ca va".


---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 23-07-2007 à 15:42:39    

ben j'ai pas mieux à te proposer pour l'instant :p
 
Je pense que ton pb est inhérent à tout SGBD...

Reply

Marsh Posté le 23-07-2007 à 21:51:38    

welcominh a écrit :

Ce serait ok s'il n'y avait qu'un seul utilisateur à la fois. Mais l'application peut être utilisée par plusieurs personnes en même temps. Donc s'il y a un insert entre mon insertion et la requete qui récupère le max de l'ID, la valeur récupérée sera faussée  :sweat:
 
(désolé de ne pas l'avoir précisé plus tot)

Il y a peut être des fonctions qui permettent de "locker" la table pour éviter toute modification entre l'insertion et la recherche du max [:figti]  
(bon, ca devient un peu une usine à gaz :o )

Reply

Marsh Posté le 24-07-2007 à 06:00:37    

Bonjour,
 
En php5, il y a ça : sqlite_last_insert_rowid.
http://www.php.net/manual/fr/funct [...] -rowid.php

Reply

Marsh Posté le 24-07-2007 à 06:00:37   

Reply

Marsh Posté le 24-07-2007 à 09:02:20    

j'ai vu ca merci. Mais je programme en Java. C'est pour ca que je cherche une méthode en SQL.
Merci quand même  :)


---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 24-07-2007 à 09:30:15    

Désolé. (Michel Denizot)

Reply

Marsh Posté le 24-07-2007 à 09:50:22    

c'est du multiclient ou pas? vu que c'est une base portable je demande

Reply

Marsh Posté le 24-07-2007 à 09:58:49    

A priori, l'application est partagée et est censée se situer sur le serveur de fichier. Les utilisateurs (employés de la boite) accèdent donc à la même ressource, application et base.


Message édité par welcominh le 24-07-2007 à 09:59:15

---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 24-07-2007 à 10:14:40    

Va voir là :
http://search.cpan.org/~adamk/DBIx-MySQLSequence-1.00/lib/DBIx/MySQLSequence.pm
 
Le principe est peut-être intéressant à reproduire pour toi.

Reply

Marsh Posté le 24-07-2007 à 10:32:01    

si ils accedent a la même application réellement c'est a dire a la même instance de l'application, alors tu ne devrais pas trop te casser la nenette et juste faire un sigleton de ta classe qui interface ta db

Reply

Marsh Posté le 24-07-2007 à 10:46:38    

Le principe du singleton me parait intéressant.
Mais ca ne résout pas le pb nan?
Le user 1 insert une ligne dans la table 'contact'. L'id généré est 1.  
Le user 2 insert une ligne dans la table 'contact'. L'id généré est 2.
Le user 1 récupère max(id_contact). Il récupère l'id 2 et non 1.
 
Ca marcherait si le fait d'accéder à une méthode de ce singleton bloque l'accès à cette méthode pour les autres utilisateurs, le temps de son exécution. Est-ce la cas? (c'est la 1ere fois que je rencontre cette situation)


---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 24-07-2007 à 11:05:11    

fait un trigger

Reply

Marsh Posté le 24-07-2007 à 12:22:16    

welcominh a écrit :

Le principe du singleton me parait intéressant.
Mais ca ne résout pas le pb nan?
Le user 1 insert une ligne dans la table 'contact'. L'id généré est 1.  
Le user 2 insert une ligne dans la table 'contact'. L'id généré est 2.
Le user 1 récupère max(id_contact). Il récupère l'id 2 et non 1.
 
Ca marcherait si le fait d'accéder à une méthode de ce singleton bloque l'accès à cette méthode pour les autres utilisateurs, le temps de son exécution. Est-ce la cas? (c'est la 1ere fois que je rencontre cette situation)


 
ben oui il va récuperer l'id deux, vu cette séquence je ne vois pas pourquoi il devrait récuperer l'id 1, ou alors dans ton singleton tu enchaines les deux instructions et donc le client1 récuperera directement l'id de sa derniere transaction, ou bien alors tu fais une procédure au niveau de ta db ou tu vas locker la table, enchainer les deux instructions, et faire remonter ton max id.
 
mais de toute facon tu dois gérer d'une manière ou d'une autre un sysème de transaction, tu le mets au niveau applicatif ou db ca c'est a toi de voir

Reply

Marsh Posté le 25-07-2007 à 17:46:33    

welcominh a écrit :

... Donc s'il y a un insert entre mon insertion et la requete qui récupère le max de l'ID, la valeur récupérée sera faussée  :sweat:


 
La fonction LOCK TABLES (http://dev.mysql.com/doc/refman/5. [...] ables.html) est propre à MySQL aussi ? parce que sinon tu bloques ta table le temps d'insérer puis de récupérer ton max ID ...


Message édité par mv1 le 25-07-2007 à 17:49:54
Reply

Marsh Posté le 25-07-2007 à 18:11:31    

wof. sinon tu fais juste un select sur ta sequence. et tu insères en conséquence.

Reply

Marsh Posté le 26-07-2007 à 08:53:20    

la sequence est elle aussi "partagée" si la base l'est non? donc la question de l'accès multiple reste en suspens.
J'ai convaincu mon maitre de stage de rester sur du MySQL, mais bon  [:airforceone]

 

edit: apparemment oui LOCK TABLES est propre a MySQL. A confirmer, mais j'ai cru lire qu'il nétait pas standard sql.


Message édité par welcominh le 26-07-2007 à 08:56:39

---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 26-07-2007 à 11:03:47    

mais trigger bonsang

Reply

Marsh Posté le 26-07-2007 à 19:06:30    

pour le trigger il faut voir si il doit le faire dans tous les cas, il devrait mieux définir le contexte, mais sinon une stored procedure et c'est emballé

Reply

Marsh Posté le 27-07-2007 à 08:54:07    

J'ai besoin des infos récupérées dans les champs de ma fenetre pour insérer dans la 2e table. Je peux faire ca avec un trigger ou une procédure stockée?
(parce que les seuls triggers qu'il m'est arrivé de coder ne dépendent pas de la couche logicielle)


Message édité par welcominh le 27-07-2007 à 08:55:11

---------------
Direct-download.com, le moteur de recherche pour Mega
Reply

Marsh Posté le 27-07-2007 à 11:13:50    

pas tellement de choix possible je pense:
- tu es capable d'aller rechercher l'id dans ta 2ème fenetre.
- tu dois faire remonter l'id de ton 1er insert, d'ou insertion via une procédure stockée.
- tu ne fais tes deux inserts que lors de la validation complète de tes deux formulaires.

Reply

Marsh Posté le 16-11-2011 à 21:20:10    

un petit déterrage....  :pt1cable:  :pt1cable:  
 
J'avais le même problème et voila la reponse. La fonction Native en sqlite est  
 

Code :
  1. SELECT LAST_INSERT_ROWID()

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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