2011-11-04 27 views
10

我在數據庫表中有兩列(其中包括):ExitDate和ExitReason。我們的業務邏輯要求在指定ExitDate時指定ExitReason。 ExitDate列需要允許空值,因爲在插入時該值並不總是已知的。有沒有辦法讓ExitReason列只有在ExitDate值爲null時才允許空值?我可以通過將這兩列分割成一個單獨的「退出日期」表並使它們都不可爲空來實現這一效果,但如果我不需要,它會很好。有沒有辦法讓列的可空性取決於另一列的可空性?

想法?謝謝!

+0

有無你試圖寫觸發器? – mishadoff

回答

12

假設你在SQL Server或類似的地方,你可以在你的表上使用CHECK constraint。 (不幸的是,MySQL的parses but ignoresCHECK的限制,所以你必須使用一個觸發該平臺。)

如果該表已經存在:

ALTER TABLE ADD CONSTRAINT CK_ExitDateReason 
CHECK (
     (ExitDate IS NULL AND ExitReason IS NULL) 
    OR (ExitDate IS NOT NULL AND ExitReason IS NOT NULL) 
); 

如果你正在創建的表自己:

CREATE TABLE dbo.Exit (
    ... 

    , CONSTRAINT CK_ExitDateReason CHECK ... 
); 

使用檢查約束,優選使用觸發器,因爲:

  • 個檢查約束更加明顯高於觸發
  • 約束是表定義的一部分,而不是被單獨運行的代碼,所以它的邏輯清潔
  • 我願意打賭它比觸發太
+0

+1,檢查約束肯定是要走的路。 –

+2

+1對於「這麼年輕的人」(無論如何,聲譽方面)這樣一個很好的答案。保持良好的工作:) – Bohemian

+1

@波希米亞 - 謝謝!我在[teh stacks]上有一些經驗(http://dba.stackexchange.com/users/2660/nick?tab=stats)。 :) –

0

你可以使用觸發器強制執行此操作:如果將ExitDate設置爲null以外的值,並且ExitReason被留空或設置爲null,則會拋出錯誤。

3

我可以通過將這兩列拆分成單獨的「退出日期」表並將它們設爲非空值來實現這一效果,但如果我不需要,這將會很好。

這聽起來像是一個很好的解決方案。如果你使用MySQL,那麼它可能是最好的解決方案,因爲不支持CHECK約束。

1

MS Access提供了另一種方法來實現您的目標。使用設計視圖中的表格,打開屬性表。與字段的驗證規則相反,表規則可以引用表中的其他字段。

將此作爲表的「驗證規則」屬性的一行添加。

([ExitDate] IS NULL AND [ExitReason] IS NULL) 
OR ([ExitDate] IS NOT NULL AND [ExitReason] IS NOT NULL) 

它與CHECK CONSTRAINT @NickChammas提供的相似。我將方括號放在ExitDate和ExitReason的周圍,因爲沒有方括號,Access往往把它們解釋爲文本字面值,所以增加了像這樣的引號......這是行不通的:

("ExitDate" IS NULL AND "ExitReason" IS NULL) 
OR ("ExitDate" IS NOT NULL AND "ExitReason" IS NOT NULL) 

,如果你想包括一個用戶友好的消息作爲表的有效性文本屬性顯示在驗證規則被違反,您可能會發現這種方法更方便:

"Provide values for both ExitDate and ExitReason, or leave both blank." 

編輯:由@AndriyM的建議可以作爲一個MS Access表有效性規則:

([ExitDate] Is Null) = ([ExitReason] Is Null) 
1

它可以使用CH與MS Access,但只能通過ADO。

sSQL = "ALTER TABLE customer ADD CONSTRAINT CK_ExitDateReason " _ 
& "CHECK ((ExitDate IS NULL) = (ExitReason IS NULL))" 

CurrentProject.Connection.Execute sSQL 

約束只能通過ADO刪除。但是,您可以自由添加和刪除列(字段)而不影響檢查。

也可以添加引用另一個表的檢查。

如果您使用的是表形式,返回的錯誤將是3317.您可以接受默認的消息或提供自己的像這樣:

Private Sub Form_Error(DataErr As Integer, Response As Integer) 
    If DataErr = 3317 And IsNull(Me.ExitReason) Then 
     MsgBox "Please fill in a reason" 
     Response = acDataErrContinue 
    End If 
End Sub 

更多信息:Intermediate Microsoft Jet SQL for Access 2000

相關問題