2012-08-30 109 views
2

我有兩個表,A和B的結構是這樣的:創建值的檢查約束的另一個表與空

CREATE TABLE A (
    w int NOT NULL, 
    x int NOT NULL, 
    y int NOT NULL, 
    CONSTRAINT PK_A PRIMARY KEY (w, x, y) 
) 

CREATE TABLE B (
    w int NOT NULL, 
    y int NULL, 
    z int NOT NULL 
) 

我要確保在B表中輸入任意組的值,即W和Y是表A.如果在表B中的Y值是空的,我只是想確保w是在表A

一些樣本數據,插入和預期的結果:

Table A 
w x y 
---------- 
1 1 1 
1 1 2 
1 2 1 
1 3 2 
2 1 1 

INSERT INTO B (w, y, z) VALUES (1, 1, 3) -- good 
INSERT INTO B (w, y, z) VALUES (1, NULL, 3) -- good 
INSERT INTO B (w, y, z) VALUES (1, 1, 4) -- good 
INSERT INTO B (w, y, z) VALUES (2, NULL, 3) -- good 
INSERT INTO B (w, y, z) VALUES (1, 3, 1) -- fail 
INSERT INTO B (w, y, z) VALUES (3, NULL, 1) -- fail 

任何方式爲了這個工作?如果這一點起作用,我正在使用SQL Server 2000。

+1

'如果表B中的y值爲空,我只想確保y在表A中。沒有得到這個聲明!如果B中的y值爲null,那麼表A中的'y'值應該是多少? – Vikdor

+0

謝謝,你爲我發現了一個錯字。應該是,如果表B中的y爲空,我想檢查以確保**'w'**在表A中。 – Dave

+1

除非我誤解了某些東西,這不僅僅是兩個FK限制嗎? 'B.W - > A.W'和'B.Y - > A.Y'? –

回答

2

不幸的是,您不能在B.wB.y上使用外鍵約束,因爲它們會引用A上的非唯一列。但您可以通過觸發器添加此檢查:

create trigger check_w on B for insert, update 
as 
if not exists(select * from A join inserted on A.w = inserted.w) 
begin 
    raiserror('W not in A!', 1, 1) 
    rollback transaction 
end 

GO 

create trigger check_y on B for insert, update 
as 
if 
(select y from inserted) is not null and 
not exists(select * from A join inserted on A.y = inserted.y) 
begin 
    raiserror('Y not null and not in A!', 1, 1) 
    rollback transaction 
end 

GO 

您可以將這兩個觸發器組合在一起。

另請注意,對於delete操作,您需要A上的觸發器。如果B上有匹配的行,或者您執行級聯刪除操作,則可以防止刪除。

+0

這並不完全是我在尋找約束條件,但我沒有很好地解釋它。我可以結合你的觸發器,並作出if語句:'如果不存在(select * from一個連接插入Aw = inserted.w和(Ay = inserted.y或inserted.y爲null))'尋找。不幸的是,它只適用於B的插入/更新。沒有什麼能夠阻止我向B添加某些東西,然後從A中刪除該行。使用檢查約束可以做到這一點的任何方式? – Dave

+0

哦,是的,你需要另一個觸發器(在刪除...),我相應地更新.... –

+0

我最終使用這種方法。正如我所提到的那樣,我確實合併了觸發器以滿足我的要求我還在A上添加了一個觸發器,用於更新和刪除。謝謝您的幫助。 – Dave