我有四张桌子,看起来有点像这样:
CREATE TABLE [TableA]
( [ID] INT NOT NULL IDENTITY (1, 1) PRIMARY KEY )
CREATE TABLE [TableB]
( [A_ID] INT NOT NULL FOREIGN KEY REFERENCES [TableA] ([ID])
, [Value] TINYINT NOT NULL
, PRIMARY KEY ( [A_ID], [Value] ) )
CREATE TABLE [TableC]
( [ID] INT NOT NULL IDENTITY (1, 1) PRIMARY KEY
, [A_ID] INT NOT NULL FOREIGN KEY REFERENCES [TableA] ([ID]) )
CREATE TABLE [TableD]
( [ID] INT NOT NULL IDENTITY (1, 1) PRIMARY KEY
, [C_ID] INT NOT NULL FOREIGN KEY REFERENCES [TableC] ([ID])
, [Value] TINYINT NOT NULL )
但我想在TableD
上强制执行引用完整性,以使有效值可能只是与父{{1}相关联的TableB
TableA
的值之一记录。例如:
TableC
现在,我尝试将TableA: ID
1
TableB: A_ID | VALUE
1 | 1
1 | 2
TableC: ID | A_ID
7 | 1
TableD: ID | C_ID | VALUE
1 | 7 | 1 -- Fine, Inserted
1 | 7 | 2 -- Fine, Inserted
1 | 7 | 3 -- Invalid, Rejected!
列添加到A_ID
,如下所示:
TableD
但是我收到以下错误:
Msg 1776,Level 16,State 0,Line 2
引用的表“CREATE TABLE [TableD] ( [ID] INT NOT NULL IDENTITY (1, 1) PRIMARY KEY , [C_ID] INT NOT NULL , [A_ID] INT NOT NULL , [Value] TINYINT NOT NULL , FOREIGN KEY ([C_ID], [A_ID]) REFERENCES [TableC] ([ID], [A_ID]) , FOREIGN KEY ([A_ID], [Value]) REFERENCES [TableB] ([A_ID], [Value]) )
”中没有主键或候选键与外键“TableC
”中的引用列列表匹配。Msg 1750,Level 16,State 0,Line 2
无法创建约束。查看以前的错误。
我真的不喜欢这个解决方案,因为它似乎是非规范化的 - 因为我将FK__TableD__TableC
→TableC
关系存储在两个不同的地方 - 但我想不出任何其他方式强制引用完整性(触发器除外,我想避免)。
有没有办法实现这个目标?
答案 0 :(得分:1)
是的,有办法。您可以向表unique
添加TableC
约束:
CREATE TABLE [TableC]
( [ID] INT NOT NULL IDENTITY (1, 1) PRIMARY KEY
, [A_ID] INT NOT NULL FOREIGN KEY REFERENCES [TableA] ([ID]),
CONSTRAINT UK_TableC UNIQUE ([ID], [A_ID]) )
然后您可以按照指定在表TableC
中引用TableD
:
CREATE TABLE [TableD]
( [ID] INT NOT NULL IDENTITY (1, 1) PRIMARY KEY
, [C_ID] INT NOT NULL
, [A_ID] INT NOT NULL
, [Value] TINYINT NOT NULL
, FOREIGN KEY ([C_ID], [A_ID]) REFERENCES [TableC] ([ID], [A_ID])
, FOREIGN KEY ([A_ID], [Value]) REFERENCES [TableB] ([A_ID], [Value]) )