2011-03-15 4 views
6

A와 B의 두 열이있는 mysql 테이블이 있다고 가정합니다. A 또는 B (한 번만 전체 테이블에서) 값을 한 번만 삽입 할 수 있도록 고유 키를 가질 수 있습니까?전체 mysql 테이블의 고유 키?

따라서 열 A에 'qwe'가 ​​포함되고 B에 'asd'가 포함 된 경우 두 값을 더 이상 두 열에 삽입 할 수 없습니다.

이 작동하지 않습니다

UNIQUE KEY `A` (`A`,`B`), 
UNIQUE KEY `A_2` (`A`), 
UNIQUE KEY `B` (`B`), 
UNIQUE KEY `B_2` (`B`,`A`) 

감사합니다.

편집 :

delimiter | 
create trigger unique_check before insert on mytable 
     for each row begin 
       declare alreadyexists integer; 
      select count(*) > 0 into alreadyexists from mytable 
       where A=NEW.B or B=NEW.A; 
      IF alreadyexists = 1 THEN begin 
      DECLARE dummy INT; 
     SELECT 'A OR B already exists' INTO dummy FROM mytable 
      WHERE nonexistent = 'value'; 
end; 
END IF; 
END;| 

그러나, 나는 'A 또는 B가 이미 존재'이 표시되지 않는 오류 메시지 만 :

오류를 나는 다음과 같은 트리거 이러한 목표를 달성 할 수 있었다 1054 (42S22) : 'where 절'에서 알 수없는 열 '없음'

다시 한번 감사드립니다!

+0

또 다른 옵션으로 '값', 'a', 'b'및 'b'가 비트 인 테이블을 가질 수 있으며 값 (고유해야 함)이 입력되면 또한 a 또는 b를 1로 설정합니다. 누군가가 'a'와 'b'모두 1을 넣는다면 여전히 문제가되는 것 같지만 다른 방법이 있습니다. – Harold

답변

2

예 가능합니다.

1 방법은 당신은 BEFORE INSERT 트리거를 생성하고 값이 이미 다른 컬럼/테이블에서 발견되는 경우 오류를 반환 할 필요가

입니다. 이 blog post

MySQL의 트리거에서

: 어떻게 당신은 INSERT, UPDATE를 중단하거나 트리거 삭제합니까? EfNet의 #mysql 사용자 질문 :

비즈니스 규칙이 실패한 경우 트리거를 중단하려면 어떻게해야합니까? 5.0에서

및 5.1 당신은 트리거가 실패하고 의미있는 오류 메시지를 전달하기 위해 약간의 속임수에 리조트해야합니다. MySQL의 저장 절차 질문이 오류 처리에 대해 말한다 :

SP 11 마의 SP는 "이 응용 프로그램의 오류를 발생"하는 성명을 "인상"이? 죄송합니다, 현재는 아닙니다. SQL 표준 SIGNAL 및 RESIGNAL 문은 TODO에 있습니다.

아마도 MySQL의 5.2 MySQL의에서 바로 도난이 해킹 쓸모 절차 프로그래밍을 저장하게됩니다 SIGNAL 문이 포함됩니다. 무엇 해킹 무엇입니까? 이 존재하지 않는 열을 MySQL이 사용하려고 시도 할 것입니다. 추한? 예. 작품입니까? 확실한.

CREATE TRIGGER mytabletriggerexample 
BEFORE INSERT 
FOR EACH ROW BEGIN 
IF(NEW.important_value) < (fancy * dancy * calculation) THEN 
    DECLARE dummy INT; 

    SELECT Your meaningful error message goes here INTO dummy 
     FROM mytable 
     WHERE mytable.id=new.id 
END IF; END; 

Transactions

트랜잭션 테이블 (이노)에 데이터를 삽입하는 트랜잭션과 절차를 사용하여 당신은 또한 할 수있는 또 다른 방법

, 트리거 쓰기에서

오류 상태 :

이 같은 절차 무언가에

:

set @error=0; 
start transaction 
do insert 
if @error>0 then rollback; 
else commit; 
+0

도움을 주셔서 감사합니다. – atlau

1

적절한 (간단한) 방법을 설정하지 않는 제공하는 A 또는 B에서 첫 번째 널 (null) 값을 얻을 수 유착을 사용할 수 있습니다 이 관계를 수행하려면 T1과 T2라는 두 개의 테이블을 작성하십시오. 여기에서 T2는 외부 키 관계 (다 대일)가 T1로 돌아갑니다. 고유 인덱스/제약 T2.yourUniqueColumn에 선언하고 해당 열의 값을 구별해야하는 경우, T2에 다른 열을 추가한다 : 당신은 처음에이 방법으로 T2를 채울 수

T1 
    id 
    foo 


    T2 
    t2id 
    t1id fk references T1 
    yourUniqueColumn [unique index/constraint] 
    extraColumnToDescribeTheValueInUniqueColumn  

(가정 자동 증가 T2에서 PK) : 규칙 -의 엄지, 당신은 자신을 절차 적으로 관계형 데이터베이스 작업 일을 찾을 때마다로

insert into T2 
    (t1id, yourUniqueColumn, extraColumn) 
    select t1.id as t1id, T1.A as yourUniqueColumn, 'A' as extraColumn from T1 


    insert into T2 
    (t1id, yourUniqueColumn, extraColumn) 
    select T1.id as t1id, T1.B as yourUniqueColumn, 'B' as extraColumn from T1 

, 그것은 리팩토링을 다시 걸음을하고 생각하는 시간이다.

관련 문제