2012-05-23 47 views
1

假設有兩個表A和B.
A包含字段:id,a1,a2。
B包含字段:id,b1,b2。如何在SQL Server中創建這種約束?

從表A到表B根據id字段從一個到多個關係展開。

現在我們假設我想在表b上創建一個唯一約束,禁止我插入基於b1,b2和a1的重複記錄。那可能嗎?

回答

3

您必須擁有a1副本才能出現在B中,以強制執行此操作爲約束。如果您不希望對用戶可見,請創建一個包含所有B s列+ a1的表格(例如_B),然後創建一個名爲B的視圖(具有合適的插入觸發器以填充a1),該視圖隱藏本專欄。

您還應該創建一個A在超密鑰和ida1,並使用外鍵約束(可能與ON UPDATE CASCADE)從B在這兩列,以確保這個複製列正確匹配A相應的值。

不管你是否決定這應該是唯一的外鍵,還是繼續保持「正確」的一個(僅僅是id)另外是一個口味問題。


如:

CREATE TABLE dbo.A (ID int not null,a1 int not null,a2 int not null, 
    constraint PK_A PRIMARY KEY (id), 
    constraint UQ_A_a1_check UNIQUE (id,a1) 
) 
CREATE TABLE dbo._B (ID int not null,a1 int not null,b1 int not null,b2 int not null, 
    constraint PK_B PRIMARY KEY (a1,b1,b2), 
    constraint FK_B_A FOREIGN KEY (id) references A (id), 
    constraint DRI_B_A_a1_check FOREIGN KEY (id,a1) references A (id,a1) on update cascade 
) 
GO 
CREATE VIEW dbo.B 
WITH SCHEMABINDING 
AS 
    select id,b1,b2 from dbo._B 
GO 
CREATE TRIGGER T_B_I on dbo.B instead of insert 
AS 
    INSERT INTO dbo._B (id,a1,b1,b2) 
    SELECT i.id,a.a1,i.b1,i.b2 
    FROM 
     inserted i 
      inner join 
     dbo.A a 
      on 
      i.id = a.id 
GO 
+0

+1 。是否需要'約束FK_B_A'(在添加'DRI_B_A_a1_check'之後)? –

+0

看到第三段 - 正如我所說,這是一個品味問題。它「記錄」了真實的關係(儘管'DRI_'有足夠的希望能夠向下一個人提供線索,表明它是爲了DRI目的而不是作爲真正的外鍵) –

+0

聽起來就像在表B中添加a1一樣那麼對我而言,這將是一個更簡單的解決方案。值得慶幸的是,這是一個永不改變的價值,所以我應該能夠做到這一點,而不用擔心標題和細節表進入不一致的狀態。 –

0

一種解決方案可能是創建表A重複值的函數測試並添加檢查約束的功能,引用表B.