J'insère dans le tableau suivant en utilisant LuaSQL avec PtokaX API.
CREATE TABLE `requests` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`ctg` VARCHAR(15) NOT NULL,
`msg` VARCHAR(250) NOT NULL,
`nick` VARCHAR(32) NOT NULL,
`filled` ENUM('Y','N') NOT NULL DEFAULT 'N',
`dated` DATETIME NOT NULL,
`filldate` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `nick_msg` (`nick`, `msg`),
UNIQUE INDEX `ctg_msg` (`ctg`, `msg`)
)
COMMENT='Requests from users in any of the categories.'
COLLATE='utf8_general_ci'
ENGINE=MyISAM;
Maintenant, mon problème est, lorsqu'un utilisateur (représenté par nick
) essaie à nouveau d'insérer la même demande, l'index UNIQUE
est vérifié et le script renvoie un faux. Cela provoque l'échec de mon script et je dois redémarrer le script.
Y a-t-il quelque chose que je peux faire dans le
INSERT ... ON DUPLICATE KEY
commande pour qu'elle ne fasse rien ou du moins ne renvoie PAS d'erreur en cas deDUPLICATE KEY
?
Sinon, je devrais aller pour mettre à jour mon champ dated
avec la nouvelle valeur DATETIME
.
Trois façons. Soit IGNORE
erreurs en double:
INSERT IGNORE
... ; -- without ON DUPLICATE KEY
ou essayez de faire une mise à jour redondante en cas de doublon:
INSERT
...
ON DUPLICATE KEY UPDATE
id = id ;
ou vérifiez les doublons avant d'insérer:
INSERT INTO requests
(id, ctg, msg, nick, filled, dated, filldate)
SELECT
NULL, 'urgent', 'Help!', 'Hermione', 'Y', NOW(), NOW()
FROM
dual
WHERE NOT EXISTS
( SELECT * FROM requests WHERE (nick, msg) = ('Hermione', 'Help!') )
AND NOT EXISTS
( SELECT * FROM requests WHERE (ctg, msg) = ('urgent', 'Help!') ) ;
Une différence entre la 3ème manière et les deux premières est que lorsqu'il y a des doublons, le id
ne sera pas incrémenté. Avec INSERT IGNORE
et INSERT ... ON DUPLICATE KEY
, il sera incrémenté automatiquement et puisque l'insertion ne sera pas effectuée, vous aurez des lacunes dans les valeurs de id
.
Je dois également ajouter que vos scripts doivent toujours vérifier les erreurs et ne pas échouer quand il y en a. Toute requête ou instruction peut échouer et renvoyer des erreurs de temps en temps, pour diverses raisons. Les astuces ci-dessus ne vous éviteront qu'un seul type d'erreur.
Les options sont super, j'en connais juste une quatrième. Vous pouvez créer une procédure comme suit (MySQL 5.5 ou supérieur).
DELIMITER ;;
CREATE PRODECURE...
...necessary parameters...
BEGIN
DECLARE v_dups BIGINT;
DECLARE CONTINUE HANDLER FOR 1062 SET v_dups = v_dups + 1;
-- RUN SIMPLE INSERT, IF IT TAKES DUPLICATE KEY NOTHING HAPPENS
END;;