Mysql

兩個可以為空的列之一需要具有值

  • February 28, 2015

沒有解釋的問題:

反正有 2 個空值的約束,總是需要 1 有值嗎?例如,兩個日期列都為空,但至少有1 個需要有值

問題描述:

假設我有一個名為 Expense 的表

並有 2 個日期:

prevision_expense_expiration_date DATE NULLABLE

這兩列的邏輯如下:

我買了一些東西,我知道我必須支付它,某個日期,比如電話費。我將使用費用_payment_date 將此作為費用輸入。這個日期是我應該支付的假定日期,而不是實際的支付日期,比如發票的到期日期。

在其他情況下,我會出售某些提供商的禮品卡以提供服務。只有當客戶兌換卡時,我可能需要向我的提供商購買轉移給我的客戶的服務。因此禮品卡有一個到期日期,我想為那個“費用”做一個預置,而不是在禮品卡有效期內作為費用插入,如果禮品卡過期,那個“費用”不應該進入賬戶系統。

我知道我可以有 2 個同樣稱為 prevision_expense 和 confirm_expense 的表,但聽起來不正確,所以我在同一個表中有 2 個日期,可以為空,但我想限製或其他東西,以便始終需要一個。

還有另一種可能的策略:

payment_date DATE NOT NULL is_prevision_date BOOL NOT NULL

因此,在這種情況下,如果日期為 prevision,則布爾值為 1,否則為 0。沒有空值,一切都很好。除了我希望在第一次我有一個預置日期時儲存兩個值的選項,然後(讓我們說兩天后)有一個確認的費用日期,在這種情況下,使用策略 2 我將沒有該選項。

我在數據庫設計中做錯了嗎?:D

JD Schmidt 的答案的一個版本,但沒有額外專欄的尷尬:

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

引用自:https://dba.stackexchange.com/questions/43284