2013-08-09 12 views
8

Tôi có một bảng có 4 cột (ID (PK, int, NOT NULL), col1 (NULL), col2 (NULL), col3 (NULL))Có thể KIỂM TRA ràng buộc hành động như thể khác?

Id muốn thêm ràng buộc CHECK (cấp bảng) tôi nghĩ) để:?

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

và nếu col3 là NOT NULL sau đó col1 vÀ col2 phải là NULL

tức col3 nên được null nếu col1 và col2 không phải là null hoặc ngược lại

Tôi rất mới đối với máy chủ SQL và SQL mặc dù Tôi không chắc chắn làm thế nào để thực sự thực hiện điều này hoặc thậm chí nếu nó có thể/nên được thực hiện?

Tôi nghĩ rằng có lẽ:

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

Nhưng tôi không chắc chắn nếu khung có thể được sử dụng để nhóm logic như thế này?

Nếu không, cách tốt nhất có thể được triển khai?

+0

Không, bảng tôi đang ở trên một máy chủ trực tiếp với rất nhiều khác công cụ mà công việc sử dụng, vì vậy tôi không muốn vít những thứ lên: O – Toby

+2

Bạn không có một môi trường phát triển tương đương? – Yuck

+0

Không, không có cách nào để thiết lập một ở đây hoặc, khác thats làm thế nào tôi đã có thể bắt đầu (cũng như tôi đã đề cập Im rất mới tại SQL và sẽ không biết bắt đầu từ đâu cài đặt SQL server hoặc DB lên từ đầu) – Toby

Trả lời

11

Tuyệt đối, bạn có thể làm điều này. Xem này sqlfiddle.

Tuy nhiên, bạn cần đảm bảo bạn đã đặt đúng logic của mình. Bạn nên không bao giờ trộn AND và OR trong cùng phạm vi ngoặc vuông. Vì vậy:

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

nhu cầu để trở thành:

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

Hoặc:

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

Tùy thuộc vào ý định của bạn.

+0

Cảm ơn - cũng cảm ơn vì đã cho thấy sqfiddle, không biết rằng đã tồn tại, sẽ rất tiện dụng :) – Toby

+0

nhưng nó sẽ kiểm tra cho cả hai điều kiện có nghĩa là viceversa quá ?? – Dhaval

+0

@Dhaval: Bạn có thể muốn chỉ ra rằng logic nên đơn giản là '((col1 NOT NULL AND col2 NOT NULL AND col3 NULL) HOẶC (col3 NOT NULL AND col1 NULL AND col2 NULL))'. Vấn đề với điều này là nó sẽ luôn luôn thực thi rằng 'col1' và' col2' có cùng trạng thái. Tôi nghĩ rằng OP cố tình không làm điều này bởi vì 'col3' nên là NULL nếu _one_ của' col1' hoặc 'col2' là NOT NULL. – PinnyM

3

Chỉ cần cẩn thận để không nhầm lẫn với dấu ngoặc vuông.

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

Tôi có thể nói tạo ra một UDF như dưới đây

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 

và sau đó thêm tuyên bố kiểm tra sau trong bảng của bạn

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

Chà, đó là quá xa so với đầu của tôi ! Bạn có thể giải thích tại sao làm điều này sẽ tốt hơn so với ràng buộc AND/OR đơn giản? – Toby

+1

@Toby .. bạn nói đúng ... Tôi vừa cố giải thích điều này có thể được thực hiện – Dhaval