2013-07-17 2 views
0

이 테이블을 가지고 col1 col2 col3, col1이 기본 키입니다. 이제 col2와 col3에 대해 고유 제한 조건을 추가하고 싶습니다. alter table add 제약 조건을 사용했지만 이미 테이블에 중복 레코드가있는 것 같습니다. 작동하도록 만들기 위해 삭제해야하지만 기존 레코드를 모두 유지해야하는 경우 새로 추가 된 레코드가 col2 및 col3의 고유 제한 조건인지 확인하는 방법은 무엇입니까?기존 복제 된 레코드를 삭제하지 않고 2 열에 대해 고유 제한 조건을 추가하려면 어떻게합니까?

+1

테이블에 여전히 유효하지 않은 데이터가있는 경우 제약 조건이 무엇입니까? 데이터를 수정 한 다음 제한 조건을 추가하십시오. – GolezTrol

+0

그러나 기존 레코드를 유지하면 고유하지 않습니다. 이전 레코드를 사용하는 모든 쿼리가 원하는 작업을 수행하지 않는다는 의미입니다. 그래서, 왜 그런 일을하고 싶습니까? – Ben

+0

업데이트를 사용하여 복제본을 수정할 수 있습니다 (col2 및 col3 다음에 "-col1"을 추가하여 고유하게 만듭니다). 선택한 중복에 대한 업데이트로 인해 복제 된 행에서만이 작업을 수행하면됩니다. – Rik

답변

1

정확하게 이해하면 현재 복제본을 남기고 싶지만 새로운 복제본을 추가하지 않으시겠습니까? 개인적으로 위의 의견을 따르 겠지만 비즈니스 요구를 충족시키지 못한다면 이해합니다.

불행히도 제약 조건은 설명 할 때 요구 사항을 충족하지 못합니다. 테이블 수준이 아닌 데이터를 삽입하는 소프트웨어의 중복 논리를 제어하려고 할 수 있습니다. 예를 들어 다음은 val3이 테이블에없는 경우에만 행을 추가합니다. 이해가 되니?

INSERT INTO MyTable (col1, col2, col3, col4) 
VALUES (val1, val2, val3, val4) WHERE NOT col3 = val3; 

OR 대신 OF 트리거를 발생 할 수 있습니다. SQL에는 값을 입력하기 바로 전에 비교할 수있는 특별한 임시 '삽입 된'테이블이 있습니다. 따라서 "이 값을 삽입하고 기다리십시오! 만 임시의 행이 테이블을 MyTable에있는 기존 행과 일치하지 않는 '삽입'경우

CREATE TRIGGER no_duplicates_in_MyTable ON MyTable 
INSTEAD OF INSERT 
AS 
BEGIN 
SET NOCOUNT ON 
IF (NOT EXISTS (SELECT M.val3 
     FROM MyTable M, inserted I 
     WHERE M.val3 = I.val3)) 
    INSERT INTO MyTable 
     SELECT val1, val2, val3, val4 
     FROM inserted 
END 

. "를 삽입 또는 당신은 AFTER 삽입 트리거 테이블 수준에서 로직을 처리 할 수 ​​있지만, 그것은이다 ..이 같은 남았습니다 작은 당신은 어떤 경우에는, 기존의 중복을 삭제할 수 뭔가;

CREATE TRIGGER delete_duplicates_MyTable 
AFTER INSERT ON MyTable 
BEGIN 
    DELETE FROM MyTable 
    WHERE val3 NOT IN (SELECT MIN(val3) 
          FROM MyTable 
          WHERE val1 = new. val1) 
    AND val1 = new. val1; 
END; 

이 귀하의 비즈니스 요구 사항을 충족하지 않는 경우 나 문의 사항이 있으면 모르거나하자

편집 : @. Rik이 정확합니다.이 트리거는 INSERT 트리거이므로 작동하지 않습니다. 누군가의 코드가 값을 복제본으로 변경할 수있게합니다. UPDATE 트리거를 시도하십시오. INSERT to UPDATE가 변경되면서 주변을 둘러 볼 수 있습니다.

+0

고맙습니다. 임시 테이블을 사용해 보았습니다. 불행히도 mysql에는 기본 '삽입 된'테이블이 없으므로 NEW를 사용합니다.F1 F2 F3 대신,하지만 여전히 – Evelyn1986

+0

내가 (NOT있는 경우 정말 각 행에 대해 버전 ON INSERT 전에 트리거 no_duplicates_in_version 을 만들 코멘트 – Evelyn1986

+0

에 코드를 게시 을 시작하는 방법을 모르는 미안 해요 (SELECT 버전 구문 오류가 발생했습니다 버전 로부터 을 .product_id WHERE version.produc_id = NEW.product_id)) 버전 (ID, 이름, PRODUCT_ID) VALUES (NEW.id, NEW.name, NEW.product_id) END – Evelyn1986

0

개인적으로 나는 다른 사람의 의견과 함께 가고 싶습니다. 실제로 데이터를 수정 한 다음 제한 조건을 추가해야합니다.

그러나 MERGE 엔진을 사용하는 것이 가능한 해결책 일 수 있습니다. 기본적으로 한 테이블에있는 데이터를 유지하고 거의 동일한 두 번째 테이블을 생성합니다. 차이점 만이 이번에는 색인이 고유합니다.

CREATE TABLE t1 (
    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    message CHAR(20), 
    key whatever (message) 
    ) ENGINE=MyISAM; 

CREATE TABLE t2 (
    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    message CHAR(20), 
    unique key whatever (message) 
    ) ENGINE=MyISAM; 

INSERT INTO t1 (message) VALUES ('Testing'),('Testing'),('t1'); 
INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2'); 

CREATE TABLE total (
    a INT NOT NULL AUTO_INCREMENT, 
    message CHAR(20), INDEX(a)) 
    ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST; 

select * from total; 
/*Here you can see, that there are duplicate values*/ 

insert into total (message) values ('Testing'); 
/*but this results in a duplicate key error*/ 

insert into total (message) values ('it work\'s'); 
/*whereas this doesn't*/ 

병합 엔진 here에 대해 자세히 알아보기 :

이 예를 참조하십시오.

관련 문제