[SQL]Insertion d'un enregistrement sans doublon

Insertion d'un enregistrement sans doublon [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 07-03-2008 à 16:52:19    

Bonjour,
 
Voici la structure d'une de mes tables dans MySQL :

mysql> describe my_semaphores;
+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| ID        | int(11)     | NO   | PRI | NULL    | auto_increment |
| ID_CLIENT | int(11)     | NO   |     | 0       |                |
| SEMAPHORE | varchar(30) | NO   | MUL |         |                |
+-----------+-------------+------+-----+---------+----------------+
3 rows in set (0.20 sec)


Plusieurs process/threads sont susceptibles de vouloir insérer des enregistrements où le champ SEMAPHORE peut être identique mais le champ ID_CLIENT différent.
Par exemple : INSERT INTO `MY_SEMAPHORES` (`ID_CLIENT`,`SEMAPHORE`) VALUES (1234,'tartampion'); pour un thread et la même chose pour un autre thread avec juste l'id_client différent.
Seul le 1234 serait différent suivant le thread.
 
Ce que je souhaite c'est qu'il ne reste qu'un seul enregistrement au final (pas de doublon de 'tartampion' avec l'un ou l'autre des ID_CLIENTS).
 
Je ne peux ni utiliser LOCK TABLES (car les autres threads souhaitant travailler sur d'autres enregistrements doivent pouvoir le faire) ni GET_LOCK (car j'ai déjà un verrou posé et utilisé) ... Je ne sais pas comment faire ...
 
Existe-t'il une solution bateau dans MySQL que je ne connaitrai pas, ou quelqu'un saurait-il comment modifier mon INSERT pour être sur d'obtenir le résultat souhaité ?
 
Merci bien !!

Reply

Marsh Posté le 07-03-2008 à 16:52:19   

Reply

Marsh Posté le 07-03-2008 à 18:07:37    

Premier élément de réponse ... je laisse créer les doublons, et ensuite je réalise une suppression :

mysql> delete from my_semaphores my_sem where my_sem.id > ANY (SELECT id from my_semaphores my_sem2 where my_sem.id <> my_sem2.id and my_sem.semaphore = my_sem2.semaphore);


Malheureusement, ça me génère une erreur :
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where my_sem.id > ANY (SELECT id from my_semaphores my_sem2 where my_sem.id <> m' at line 1
Si je remplace "delete" par "select *", j'obtiens bien la selection des doublons en trop ...
 
Je n'arrive pas à voir où est l'erreur ... Merci pour vos lumières !!!  :jap:

Reply

Marsh Posté le 13-03-2008 à 16:10:26    

pk pas un index unique entre les champs  ID_CLIENT et SEMAPHORE ?


---------------
Pays et country_code traduits : https://www.iso-country-code.com
Reply

Marsh Posté le 13-03-2008 à 16:20:38    

+1  
tu pourras ensuite utiliser replace


---------------
Software and cathedrals are much the same - first we build them, then we pray.
Reply

Marsh Posté le 13-03-2008 à 18:21:33    

ragondin a écrit :

pk pas un index unique entre les champs  ID_CLIENT et SEMAPHORE ?


J'ai déjà un champ `ID`qui est clé unique. Je ne peux pas en créer un deuxième ...... si ?  :??:  
 

Citation :

+1  
tu pourras ensuite utiliser replace


Tout a fait d'accord avec toi si je peux mettre en place la proposition de ragondin !
 
 
Pour le moment, je laisse créer les doublons puis j'envoi deux requêtes qui les suppriment en laissant seulement le plus ancien :

SELECT MIN(`ID`) as `minID` FROM `MY_SEMAPHORES` WHERE `SEMAPHORE`='leSemaphore';
DELETE FROM `MY_SEMAPHORES` WHERE `SEMAPHORE`='leSemaphore' AND `ID`>minID


 
Si la procédure de ragondin est finallement faisable, je ne vois pas pour autant comment définir ma table dans ce sens ...
Quel "CREAT TABLE" dois-je effectuer ?
 
Merci encore pour votre aide !! :jap:

Reply

Marsh Posté le 14-03-2008 à 16:16:47    

Pas de problème pour créer 2 index.

Code :
  1. ALTER TABLE `my_semaphores` ADD UNIQUE (
  2. `ID_CLIENT` ,
  3. `SEMAPHORE`
  4. )


---------------
Pays et country_code traduits : https://www.iso-country-code.com
Reply

Sujets relatifs:

Leave a Replay

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