2013-08-09 6 views
8

Mam tabeli z kolumny 4 (ID (PK, int not null), Col1 (NULL), COL2 (NULL), Col3 (NULL))Czy ograniczenia CHECK mogą zachowywać się jak gdyby?

Id jak dodać ograniczenie wyboru (na poziomie tabeli myślę) tak, że:?

if col1 OR col2 are NOT NULL then col3 must be NULL 

i jeśli Col3 NOT NULL wtedy col1 i col2 musi być NULL

tj Col3 powinny być null, jeśli col1 i col2 nie są nieważne lub vice versa

Jestem bardzo nowy w SQL i SQL Server choć nie jestem pewien, jak to faktycznie wdrożyć, a nawet czy można/należy wdrożyć?

Myślę, że:

CHECK ((col1 NOT NULL OR col2 NOT NULL AND col3 NULL) OR 
     (col3 NOT NULL AND col1 NULL AND col2 NULL)) 

Ale nie jestem pewien, czy uchwyty mogą być używane do grupy logikę tak?

Jeśli nie, w jaki sposób najlepiej można wdrożyć ten najlepszy?

+0

Nie, moi stoły są na serwerze na żywo z wielu innych rzeczy, których używa praca, więc nie chcę zepsuć rzeczy: O – Toby

+2

Nie masz odpowiedniego środowiska programistycznego? – Yuck

+0

Nie, nie mam sposobu, aby ustawić tutaj tutaj, inaczej to by było jakbym zaczął (także jak wspomniałem, że jestem bardzo nowy w SQL i nie wiedziałbym, gdzie zacząć ustawiać serwer SQL lub DB od zera) – Toby

Odpowiedz

11

Absolutnie, możesz to zrobić. Zobacz to sqlfiddle.

Musisz jednak upewnić się, że poprawnie rozumujesz logikę. Powinieneś nigdy mieszać ORAZ i OR w tym samym zasięgu bracketingu. Więc:

(col1 NOT NULL OR col2 NOT NULL AND col3 NULL) 

musi stać:

((col1 NOT NULL OR col2 NOT NULL) AND col3 NULL) 

czyli

(col1 NOT NULL OR (col2 NOT NULL AND col3 NULL)) 

zależności od intencji.

+0

Dzięki - również dzięki za pokazanie sqfiddle, nie wiedziałem, że istniał, będzie bardzo przydatny :) – Toby

+0

ale czy to sprawdzi, czy oba warunki oznaczają viceversa? – Dhaval

+0

@Dhaval: Prawdopodobnie chcesz zwrócić uwagę, że logika powinna być po prostu '((col1 NOT NULL AND col2 NOT NULL AND col3 NULL) LUB (col3 NOT NULL AND col1 NULL AND col2 NULL))'. Problem polega na tym, że zawsze będzie wymuszać, że "col1" i "col2" mają ten sam stan. Myślę, że PO celowo tego nie zrobił, ponieważ 'col3' powinien mieć wartość NULL, jeśli _one_ z' col1' lub 'col2' nie jest NULL. – PinnyM

3

Tylko uważaj, aby nie popełnić błędu w nawiasach.

CREATE TABLE Test1 (col1 INT, col2 INT, col3 INT); 


ALTER TABLE Test1 
ADD CONSTRAINT CHK1 
CHECK (((col1 IS NOT NULL OR col2 IS NOT NULL) AND col3 IS NULL) OR 
     ((col1 IS NULL AND col2 IS NULL) AND col3 IS NOT NULL)) 



INSERT INTO Test1 VALUES (1,1,1); --fail 
INSERT INTO Test1 VALUES (1,1,NULL); --good 
INSERT INTO Test1 VALUES (1,NULL,NULL); --good 
INSERT INTO Test1 VALUES (1,NULL,1); --fail 
INSERT INTO Test1 VALUES (NULL,NULL,1); --good 
1

powiedziałbym tworzyć UDF jak poniżej

create FUNCTION dbo.fn_check_val 
    (@col1 int , @col2 int , @col3 int) 
RETURNS bit 
AS 
BEGIN 
    declare @toRet bit 
    IF(@col1 is Not null OR @col2 is NOT NULL) 
    Begin 
     if(@col3 is null) 
     Begin 
      Set @toRet = 1 
     End 
     Else 
     Begin 
      Set @toRet = 0 
     End 
    End 
    Else 
    if(@col3 is not null) 
    Begin 
     Set @toRet = 1 
    End 
    Else 
    Begin 
     Set @toRet = 0 
    End 
return @toRet 
END 

a następnie dodać następujące oświadczenie wyboru w tabeli

([dbo].[fn_check_val]([col1],[col2],[col3])=(1)) 
+0

Wow, to jest tak daleko nad moją głową ! Czy mógłbyś wyjaśnić, dlaczego robienie tego byłoby lepsze niż proste ograniczenie AND/OR? – Toby

+1

@Toby .. masz rację ... Właśnie próbowałem wytłumaczyć, że to może być zrobione – Dhaval

Powiązane problemy