2010-08-25 45 views
2

是否有可能在輸入的記錄上有一個約束/觸發器,用於檢查用戶是否至少輸入了三個字段中的一個(全部可以爲空)。例如,我有一個數據庫用於跟蹤其他軟件中的錯誤和新功能。當發現錯誤時,創建一個功能記錄,該記錄可以有三個外鍵:discoveredID,fixedID或newFeatureID,三者都可以爲空(因爲它可能是一個發現的錯誤,固定的錯誤或添加到軟件的新功能。)但用戶在輸入數據時必須至少選擇一個。我可以使用我的數據庫控制外部程序中的輸入,但是如果有其他人寫入程序,他們可能不會將該檢查置於原地,所以我想阻止他們這樣做並輸入損壞的數據。SQL約束/觸發器 - 是否可以編寫一個約束來檢查「何時插入一條記錄,它必須包含兩個字段之一」?

+0

歡呼爲編輯傢伙,有人在我的補充上添加了一個自動更正來限制約束,argh lol。 – 2010-08-25 12:15:17

回答

3

使用SQL Server,添加一個Table level check constraint就足夠了。

CREATE TABLE Bugs (
    discoveredID INTEGER 
    , fixedID INTEGER 
    , newFeatureID INTEGER 
) 

ALTER TABLE Bugs ADD CONSTRAINT CKC_AtLeastOne CHECK (COALESCE(discoveredID, fixedID, newFeatureID) IS NOT NULL) 

INSERT INTO Bugs VALUES (NULL, NULL, 1) 
INSERT INTO Bugs VALUES (NULL, 1, NULL) 
INSERT INTO Bugs VALUES (1, NULL, NULL) 
INSERT INTO Bugs VALUES (NULL, NULL, NULL) -- Fails 

DROP TABLE Bugs 
+0

感謝您的快速響應,這正是我需要的! – 2010-08-25 12:12:24

2

讀你的設計讓我覺得可能問題可能在表設計中超過創建約束/觸發器的要求。

例如,你提到你可以有3種錯誤(發現的bug,修復bug或者一個新的功能)

有沒有可能有兩個字段的組合鍵這將是錯誤類型,並在其旁邊有相關的ID字段。

所以不是: discoveredID,fixedID,newFeatureID

你剛纔: bugTypeID,錯誤ID

隨着這一變化,你可以只專注於bugTypeID是1,2或3.

+0

+1。考慮到這一點,通過正確建模數據模型,不需要檢查約束。此外,添加新類型的bug也很容易。 – 2010-08-25 11:14:11

+0

規格說「輸入數據時用戶必須至少選擇一個」。提出的超過標準化的表格設計解決了「用戶必須只選擇一個」的情況。這個建議可能是對的,或者不是......而「答案」並沒有解決實際上被問到的問題......這是相當不禮貌的IMO :) – 2010-08-25 11:57:56

+0

你是對的,雖然我已經做了一些調整設計和我仍然需要解決方案,但在我的新設計的其他地方。我想我可以在我的設計中刪除對它的需求,但考慮到時間限制不幸擊敗完美設計,這是一個可用設計的例子。我會在將來審查它,並記住你的觀點。感謝您的貢獻。 – 2010-08-25 12:12:07