2011-11-04 12 views
10

Mam dwie kolumny (między innymi) w tabeli bazy danych: ExitDate i ExitReason. Nasza logika biznesowa wymaga określenia ExitReason, jeśli określono ExitDate. Kolumna ExitDate musi zezwalać na wartości null, ponieważ wartość ta nie zawsze jest znana w momencie wstawiania. Czy istnieje sposób, aby kolumna ExitReason zezwalała na wartości null tylko wtedy, gdy wartość ExitDate ma wartość null? Mógłbym osiągnąć ten efekt, dzieląc te dwie kolumny na osobną tabelę "dat wyjścia" i czyniąc je nieobliczalnymi, ale byłoby miło, gdybym nie musiał.Czy istnieje sposób, aby nullability kolumna zależy od nullability innej kolumny?

Pomysły? Dzięki!

+0

Have próbujesz napisać spust? – mishadoff

Odpowiedz

12

Zakładając, że jesteś na serwerze SQL lub podobnym, możesz to zrobić za pomocą tabeli CHECK constraint. (Niestety, MySQL parses but ignoresCHECK ograniczeń, więc trzeba by użyć wyzwalacza na tej platformie.)

Jeśli tabela już istnieje:

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

Jeśli tworzysz tabelę siebie:

CREATE TABLE dbo.Exit (
    ... 

    , CONSTRAINT CK_ExitDateReason CHECK ... 
); 

Korzystanie ograniczenie wyboru jest korzystniejsze od wyzwalacza, ponieważ:

  • ograniczenia wyboru są bardziej widoczne niż wyzwala
  • ograniczenie jest częścią definicji tabeli, w przeciwieństwie do kodu, który jest uruchamiany osobno, dlatego logicznie czystsze
  • Jestem gotów się założyć, że jest szybszy niż wyzwalacz zbyt
+0

+1, ograniczenie kontroli jest zdecydowanie do zrobienia. –

+2

+1 Taka dobra odpowiedź dla "kogoś tak młodego" (pod względem reputacji). Kontynuuj dobrą pracę :) – Bohemian

+1

@Bohemian - Dziękujemy! Mam trochę doświadczenia tutaj na [teh stacks] (http://dba.stackexchange.com/users/2660/nick?tab=stats). :) –

0

Można to wymusić za pomocą wyzwalacza: jeśli ustawienie ExitDate ma wartość inną niż null, a wartość ExitReason jest pusta lub ma wartość null, oznacza to, że wystąpił błąd.

3

mogłem osiągnąć efekt poprzez rozdzielenie tych dwóch kolumn w osobnej tabeli „dat wyjścia” i czyni je zarówno non-pustych, ale byłoby miło, gdybym nie musiał.

To brzmi jak bardzo dobre rozwiązanie. A jeśli używasz MySQL, to prawdopodobnie najlepsze rozwiązanie, ponieważ ograniczenia CHECK nie są obsługiwane.

1

MS Access oferuje inną metodę realizacji celu. Za pomocą tabeli w widoku projektu otwórz arkusz właściwości. W przeciwieństwie do Reguły sprawdzania poprawności dla pola , reguła tabeli może odwoływać się do innych pól w tabeli.

Dodaj to jako pojedynczą linię dla właściwości Validation Rule reguły.

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

Jest podobny do dostarczonego CHECK CONSTRAINT @NickChammas. Umieściłem nawiasy kwadratowe wokół ExitDate i ExitReason, ponieważ bez nawiasów Access zwykle interpretuje je jako wartości tekstowe, więc dodaje takie cytaty ...które nie będą działać:

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

Może się okazać metoda ta bardziej wygodne, jeśli chcesz dołączyć wiadomość przyjazny dla użytkownika jako stołu Validation własności Tekst wyświetlany, gdy reguły poprawności jest łamane:

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

Edit: sugestia przez @AndriyM pracuje jako regułę walidacji tabeli MS Access:

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

jest możliwe użycie ch ecks z MS Access, ale tylko poprzez ADO.

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

CurrentProject.Connection.Execute sSQL 

Ograniczenie można usunąć tylko przez ADO. Możesz jednak dodawać i usuwać kolumny (pola) bez wpływu na sprawdzenie.

Istnieje również możliwość dodania czeku, który odwołuje się do innej tabeli.

Jeśli używasz tabelę z formularzem, błąd powrócił będzie 3317. Można zaakceptować komunikat domyślny lub dostarczyć własne tak:

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 

Dalsze informacje: Intermediate Microsoft Jet SQL for Access 2000

Powiązane problemy