Yinelenen anahtarda hiçbir şey yapma


14

PtokaX API ile LuaSQL kullanarak aşağıdaki tabloya ekliyorum.

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;

Şimdi, benim sorunum, bir kullanıcı (ile temsil edilen nick) aynı isteği tekrar eklemeye çalıştığında, UNIQUEdizin denetlenir ve komut dosyası yanlış döndürür. Bu benim komut dosyası başarısız olur ve ben komut dosyasını yeniden başlatmak zorunda.

INSERT ... ON DUPLICATE KEYHiçbir şey yapmaması veya en azından durumunda bir hata döndürmemesi için komutta yapabileceğim bir şey var mı DUPLICATE KEY?

Aksi takdirde, alanımı datedyeni DATETIMEdeğerle güncellemek için gitmem gerekir .

Yanıtlar:


23

Üç yol. Ya IGNOREyinelenen hataları:

INSERT IGNORE 
  ... ;                   -- without ON DUPLICATE KEY

veya yinelenen bir sürüm olduğunda yedek bir güncelleme yapmaya çalışın:

INSERT 
  ... 
ON DUPLICATE KEY UPDATE
  id = id ;

veya eklemeden önce kopya olup olmadığını kontrol edin:

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!') ) ;

3. yol ile ilk ikisi arasındaki fark, kopyalar idolduğunda artışın artırılmamasıdır. İle INSERT IGNOREve INSERT ... ON DUPLICATE KEYbu oto artırılır ve ekleme yapılamaz çünkü, sen değerlerinde boşluklar olacak olacak id.

Ayrıca, komut dosyalarınızın her zaman hataları kontrol etmesi ve bir tane olduğunda başarısız olmaması gerektiğini eklemeliyim. Herhangi bir sorgu veya ifade çeşitli nedenlerle başarısız olabilir ve ara sıra hata verebilir. Yukarıdaki püf noktaları sizi sadece bir tür hatadan kurtaracaktır.


1

Seçenekler harika, ben sadece dördüncü birini biliyorum. Aşağıdaki gibi bir yordam oluşturabilirsiniz (MySQL 5.5 veya üstü).

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

Güzel, son zamanlarda MySQL kullanmıyorum, bu yüzden bunu bilmiyordum. Güncelleyebilir ve üzerinde ayrıntılar verebilir misiniz: diğer (yinelenen anahtar ihlalleri değil) hataları oluşursa ne olur? Ve bu tam olarak nasıl çalışıyor (1062 ne anlama geliyor)? Sorgunun tek bir uç olması mı gerekiyor yoksa birden çok satır eklemekle mi çalışabilir?
ypercubeᵀᴹ

1062 Yinelenen satır. Yalnızca bu SQL hatası aşağıdakileri tetikler: SET v_dups = v_dups + 1;
billmask
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.