Sur la clé en double, ne rien faire


14

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' UNIQUEindex 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 la INSERT ... ON DUPLICATE KEYcommande pour qu'elle ne fasse rien ou du moins ne renvoie pas d'erreur en cas de DUPLICATE KEY?

Sinon, je devrais aller pour mettre à jour mon datedchamp avec la nouvelle DATETIMEvaleur.

Réponses:


23

Trois façons. Soit IGNOREdes 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 3e voie et les deux premières est que lorsqu'il y a des doublons, le idne sera pas incrémenté. Avec INSERT IGNOREet INSERT ... ON DUPLICATE KEY, il sera automatiquement incrémenté 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.


1

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;;

Bien, je n'ai pas utilisé MySQL récemment donc je ne le savais pas. Pouvez-vous mettre à jour et développer: que se passe-t-il si d'autres erreurs (pas des violations de clés en double) se produisent? Et comment cela fonctionne-t-il exactement (que signifie 1062)? La requête doit-elle être un simple insert ou peut-elle fonctionner avec l'insertion de plusieurs lignes?
ypercubeᵀᴹ

1062 est une ligne dupliquée. Seule cette erreur SQL déclenche: SET v_dups = v_dups + 1;
billmask
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.