假設有兩個表A和B.
A包含字段:id,a1,a2。
B包含字段:id,b1,b2。如何在SQL Server中創建這種約束?
從表A到表B根據id字段從一個到多個關係展開。
現在我們假設我想在表b上創建一個唯一約束,禁止我插入基於b1,b2和a1的重複記錄。那可能嗎?
假設有兩個表A和B.
A包含字段:id,a1,a2。
B包含字段:id,b1,b2。如何在SQL Server中創建這種約束?
從表A到表B根據id字段從一個到多個關係展開。
現在我們假設我想在表b上創建一個唯一約束,禁止我插入基於b1,b2和a1的重複記錄。那可能嗎?
您必須擁有a1
副本才能出現在B
中,以強制執行此操作爲約束。如果您不希望對用戶可見,請創建一個包含所有B
s列+ a1
的表格(例如_B
),然後創建一個名爲B
的視圖(具有合適的插入觸發器以填充a1
),該視圖隱藏本專欄。
您還應該創建一個A
在超密鑰和id
a1
,並使用外鍵約束(可能與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
一種解決方案可能是創建表A重複值的函數測試並添加檢查約束的功能,引用表B.
+1 。是否需要'約束FK_B_A'(在添加'DRI_B_A_a1_check'之後)? –
看到第三段 - 正如我所說,這是一個品味問題。它「記錄」了真實的關係(儘管'DRI_'有足夠的希望能夠向下一個人提供線索,表明它是爲了DRI目的而不是作爲真正的外鍵) –
聽起來就像在表B中添加a1一樣那麼對我而言,這將是一個更簡單的解決方案。值得慶幸的是,這是一個永不改變的價值,所以我應該能夠做到這一點,而不用擔心標題和細節表進入不一致的狀態。 –