Sql server 2008 '中的列;表';与现有主键或唯一约束不匹配
考虑两个数据库表,Sql server 2008 '中的列;表';与现有主键或唯一约束不匹配,sql-server-2008,tsql,foreign-key-relationship,Sql Server 2008,Tsql,Foreign Key Relationship,考虑两个数据库表,tbl\u One&tbl\u two tbl_One的主键是:A,B&E列 tbl\u两个的主键是:B和C 我不希望表tbl\u-Two列B中有任何值在表tbl\u-One列B中不存在 理想情况下,我希望列B为外键,但当我尝试创建此列时,会收到以下错误消息: 表“tbl_One”中的列与现有主键不匹配 或唯一约束 我怎样才能做到这一点 警告:没有更多细节,我几乎是瞎飞,我的回答是基于我可以从你的问题中假设的 如果确实要为非主键创建外键,则该外键必须是具有唯一约束的列 发件人:
tbl\u One
&tbl\u two
tbl_One
的主键是:A
,B
&E
列
tbl\u两个
的主键是:B
和C
我不希望表tbl\u-Two
列B
中有任何值在表tbl\u-One
列B
中不存在
理想情况下,我希望列B
为外键,但当我尝试创建此列时,会收到以下错误消息:
表“tbl_One”中的列与现有主键不匹配
或唯一约束
我怎样才能做到这一点 警告:没有更多细节,我几乎是瞎飞,我的回答是基于我可以从你的问题中假设的
如果确实要为非主键创建外键,则该外键必须是具有唯一约束的列
发件人:
CREATE TABLE tbl_One
(
A int,
B int UNIQUE,
E int
CONSTRAINT [PK_tbl_One] PRIMARY KEY
(
A ASC,
B ASC,
E ASC
)
)
CREATE FUNCTION dbo.CheckFunction(@B int)
RETURNS INT
AS BEGIN
RETURN (SELECT CASE COUNT(*)
WHEN 0 THEN 0
ELSE 1
END
FROM tbl_One
WHERE B=@B)
END
ALTER TABLE tbl_Two
ADD CONSTRAINT chk_CheckFunction
CHECK (dbo.CheckFunction(B) = 1)
外键约束不必仅链接到主键
另一个表中的键约束;它也可以定义为参考
另一个表中唯一约束的列
在本例中,您需要tbl_One中的B列是唯一的,要么是主键,要么是对其具有唯一约束
唯一约束:
CREATE TABLE tbl_One
(
A int,
B int UNIQUE,
E int
CONSTRAINT [PK_tbl_One] PRIMARY KEY
(
A ASC,
B ASC,
E ASC
)
)
CREATE FUNCTION dbo.CheckFunction(@B int)
RETURNS INT
AS BEGIN
RETURN (SELECT CASE COUNT(*)
WHEN 0 THEN 0
ELSE 1
END
FROM tbl_One
WHERE B=@B)
END
ALTER TABLE tbl_Two
ADD CONSTRAINT chk_CheckFunction
CHECK (dbo.CheckFunction(B) = 1)
如果B列中的数据不是唯一的,则可以创建基于函数的检查约束以实现类似效果
功能(未测试):
CREATE TABLE tbl_One
(
A int,
B int UNIQUE,
E int
CONSTRAINT [PK_tbl_One] PRIMARY KEY
(
A ASC,
B ASC,
E ASC
)
)
CREATE FUNCTION dbo.CheckFunction(@B int)
RETURNS INT
AS BEGIN
RETURN (SELECT CASE COUNT(*)
WHEN 0 THEN 0
ELSE 1
END
FROM tbl_One
WHERE B=@B)
END
ALTER TABLE tbl_Two
ADD CONSTRAINT chk_CheckFunction
CHECK (dbo.CheckFunction(B) = 1)
检查约束:
CREATE TABLE tbl_One
(
A int,
B int UNIQUE,
E int
CONSTRAINT [PK_tbl_One] PRIMARY KEY
(
A ASC,
B ASC,
E ASC
)
)
CREATE FUNCTION dbo.CheckFunction(@B int)
RETURNS INT
AS BEGIN
RETURN (SELECT CASE COUNT(*)
WHEN 0 THEN 0
ELSE 1
END
FROM tbl_One
WHERE B=@B)
END
ALTER TABLE tbl_Two
ADD CONSTRAINT chk_CheckFunction
CHECK (dbo.CheckFunction(B) = 1)
这里有一个例子来说明这一点
感谢您指出引用完整性问题Damien,删除后触发器有助于解决这个问题,但也有不足之处。这是一个很好的使用外键和触发器进行管理的方法 如果需要表B中字段B的外键,请删除字段a、E的主键,创建关系,然后将主键重置回这两个字段。在tbl_One中,三列a、B、E一起是复合键吗?你说有“主键”(复数)有点让人困惑。MasterData是什么表?tbl_One还是tblTwo?@Gizmo是tbl_One,我更正了错误消息。@AaronPalmer我不知道什么是复合键,我只选择了3列,右键单击并选择了主键。在您的场景中,您没有将
B
本身识别为这两个表中的主键。因此,B
本身不能用作与这两个表的关系中的FK。基本上,一个表中的FK必须是被引用表中的PK。当然,函数版本相当不完整,因为它不阻止任何人在将行添加到tbl\u two
后删除tbl\u one
中的最后一行。