중복 키에서 아무것도하지 마십시오


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

세 가지 방법이 있습니다. 어느 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!') ) ;

세 번째 방법과 첫 번째 방법의 차이점은 중복이있을 때 id증가하지 않는다는 것입니다. INSERT IGNORE및을 사용하면 INSERT ... ON DUPLICATE KEY자동 증분되며 삽입이 완료되지 않으므로의 값에 차이가 id있습니다.

또한 스크립트는 항상 오류를 확인해야하며 오류가있을 때 실패하지 않아야합니다. 여러 가지 이유로 인해 쿼리 또는 명령문이 실패하고 때때로 오류를 리턴 할 수 있습니다. 위의 트릭은 한 가지 종류의 오류 만 방지합니다.


1

옵션은 훌륭합니다. 네 번째 옵션 만 알고 있습니다. 다음과 같이 프로 시저를 작성할 수 있습니다 (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;
billmask
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.