重複キーでは何もしません


14

PtokaX APIでLuaSQLを使用して、次の表に挿入しています。

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;

さて、私の問題は、ユーザー(で表されるnick)が同じリクエストを再度挿入しようとすると、UNIQUEインデックスがチェックされ、スクリプトがfalseを返すことです。これにより、スクリプトが失敗し、スクリプトを再起動する必要があります。

私が行うことができますが何かであるINSERT ... ON DUPLICATE KEYことは何もしないかで、少なくともの場合にエラーを返さないように、コマンドはDUPLICATE KEY

それ以外の場合はdated、新しいDATETIME値でフィールドを更新する必要があります。

回答:


23

3つの方法。どちらのIGNORE重複エラー:

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

または、重複がある場合に冗長な更新を試行します。

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

または、挿入する前に重複を確認します。

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番目の方法と最初の2つの方法の違いは、重複がある場合、id増分されないことです。INSERT IGNOREおよびを使用するとINSERT ... ON DUPLICATE KEY、自動的に増分され、挿入が行われないため、の値にギャップが生じますid

また、スクリプトは常にエラーをチェックし、エラーが発生しても失敗しないことを追加する必要があります。さまざまな理由により、クエリまたはステートメントは失敗し、エラーを返すことがあります。上記のトリックは、1種類のエラーからあなたを救うだけです。


1

オプションは素晴らしいです、私は4番目のものを知っています。次の手順を作成できます(MySQL 5.5以降)。

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

いいですね、最近MySQLを使用していないので、それを知りませんでした。更新して詳しく説明してください:他の(重複キー違反ではない)エラーが発生した場合はどうなりますか?そして、これは正確にどのように機能しますか(1062の略)?クエリは単一の挿入である必要がありますか、それとも複数行の挿入で動作しますか?
ypercubeᵀᴹ

1062は複製された行です。このSQLエラーのみがトリガーされます。SET v_dups = v_dups + 1;
ビルマスク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.