문제

fieldA와 fieldB가 모두 NULL이 될 수 없도록 MySQL에서 NULL이 아닌 제약 조건을 만드는 가장 좋은 방법은 무엇입니까?다른 필드에 NULL이 아닌 값이 있는 한 둘 중 하나가 그 자체로 NULL인지는 상관하지 않습니다.그리고 둘 다 NULL이 아닌 값을 갖고 있다면 훨씬 더 좋습니다.

도움이 되었습니까?

해결책

MySQL 5.5 도입 신호, 우리는 Bill Karwin의 답변에 추가 열이 필요하지 않습니다. Bill은 또한 업데이트를위한 트리거가 필요하다고 지적 했으므로 나는 그것을 포함시켰다.

CREATE TABLE foo (
  FieldA INT,
  FieldB INT
);

DELIMITER //
CREATE TRIGGER InsertFieldABNotNull BEFORE INSERT ON foo
FOR EACH ROW BEGIN
  IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = '\'FieldA\' and \'FieldB\' cannot both be null';
  END IF;
END//
CREATE TRIGGER UpdateFieldABNotNull BEFORE UPDATE ON foo
FOR EACH ROW BEGIN
  IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = '\'FieldA\' and \'FieldB\' cannot both be null';
  END IF;
END//
DELIMITER ;

INSERT INTO foo (FieldA, FieldB) VALUES (NULL, 10); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (10, NULL); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (NULL, NULL); -- gives error
UPDATE foo SET FieldA = NULL; -- gives error

다른 팁

이것은 귀하의 질문에 대한 직접적인 답변이 아니라 몇 가지 추가 정보입니다.

여러 열을 처리하고 모두 null인지 또는 하나가 null이 아닌지 확인할 때 일반적으로 다음을 사용합니다. COALESCE() - 목록이 늘어나도 간단하고 읽기 쉽고 유지 관리가 쉽습니다.

COALESCE(a, b, c, d) IS NULL -- True if all are NULL

COALESCE(a, b, c, d) IS NOT NULL -- True if any one is not null

이는 트리거에서 사용할 수 있습니다.

@SKLIVVZ : MySQL 5.0.51a로 테스트하면 수표 제약 조건을 구문 분석하지만 시행하지는 않습니다. 오류없이 (null, null)를 삽입 할 수 있습니다. Myisam과 Innodb를 모두 테스트했습니다. 그 후 Show Create 테이블을 사용하면 테이블을 정의 할 때 오류가 주어지지 않았지만 검사 제약이 테이블 정의에 있지 않음을 보여줍니다.

이것은 일치합니다 MySQL 매뉴얼 "확인 절은 구문 분석되지만 모든 스토리지 엔진에 의해 무시됩니다."

따라서 MySQL의 경우 트리거를 사용 하여이 규칙을 시행해야합니다. 유일한 문제는 MySQL 트리거가 오류를 올리거나 삽입 작업을 중단 할 방법이 없다는 것입니다. 트리거에서 오류를 일으키기 위해 할 수있는 한 가지는 NULL 열을 NULL로 설정하는 것입니다.

CREATE TABLE foo (
  FieldA INT,
  FieldB INT,
  FieldA_or_FieldB TINYINT NOT NULL;
);

DELIMITER //
CREATE TRIGGER FieldABNotNull BEFORE INSERT ON foo
FOR EACH ROW BEGIN
  IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN
    SET NEW.FieldA_or_FieldB = NULL;
  ELSE
    SET NEW.FieldA_or_FieldB = 1;
  END IF;
END//

INSERT INTO foo (FieldA, FieldB) VALUES (NULL, 10); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (10, NULL); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (NULL, NULL); -- gives error

업데이트 전에 유사한 트리거도 필요합니다.

이것은 그러한 제약 조건에 대한 표준 구문이지만 MySQL은 나중에 제약을 행복하게 무시합니다.

ALTER TABLE `generic` 
ADD CONSTRAINT myConstraint 
CHECK (
  `FieldA` IS NOT NULL OR 
  `FieldB` IS NOT NULL
) 

SQL Server에서 비슷한 일을했는데 MySQL에서 직접 작동하는지 확실하지 않습니다.

ALTER TABLE tableName ADD CONSTRAINT constraintName CHECK ( (fieldA IS NOT NULL) OR (fieldB IS NOT NULL) );

적어도 나는 그것이 구문이라고 믿습니다.

그러나 테이블 전체에서 점검 제약 조건을 만들 수 없으며 한 테이블 내에서만 열만 확인할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top