【问题标题】:The columns in 'table' do not match an existing primary key or unique constraint“表”中的列与现有主键或唯一约束不匹配
【发布时间】:2014-08-14 10:56:57
【问题描述】:

考虑两个数据库表,tbl_Onetbl_Two

tbl_One 的主键是:AB & E

tbl_Two 的主键是:B & C

我不希望表tbl_TwoB 中不存在表tbl_OneB 中的任何值。

理想情况下,我希望列 B 成为外键,但是当我尝试创建它时,我收到以下错误消息:

表“tbl_One”中的列与现有主键不匹配 或 UNIQUE 约束。

我怎样才能做到这一点?

【问题讨论】:

  • 在 tbl_One 中,A、B、E 三列一起是复合键吗?你说有“主键”(复数)有点令人困惑。
  • MasterData 是什么表? tbl_One 还是 tblTwo?
  • @Gizmo 它是 tbl_One,我更正了错误消息。
  • @AaronPalmer 我不知道什么是复合键,我只是选择了3列,右键选择主键。
  • 在您的方案中,您尚未将 B 本身标识为任一表中的 PK。因此,B 本身不能用作与这两个表的关系中的 FK。基本上,一个表中的 FK 必须是被引用表中的 PK。

标签: sql-server-2008 tsql foreign-key-relationship


【解决方案1】:

警告:没有更多细节,我几乎失明了,我的回答是基于我从你的问题中可以假设的。

如果您确实想为非主键创建外键,则它必须是具有唯一约束的列。

来自Books Online

FOREIGN KEY 约束不必只链接到 PRIMARY 另一个表中的 KEY 约束;也可以定义为引用 另一个表中 UNIQUE 约束的列。

在这种情况下,您需要 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
    )
)

如果是B列数据不唯一的情况,可以创建一个基于函数的CHECK约束来达到类似的效果。

功能(未测试):

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

CHECK 约束:

ALTER TABLE tbl_Two
ADD CONSTRAINT chk_CheckFunction
CHECK (dbo.CheckFunction(B) = 1)

这是一个证明这一点的SQL Fiddle

感谢 Damien 指出参照完整性问题,AFTER DELETE 触发器可以帮助解决这个问题,但也有缺点。这是一个很好的 discussion on referential integrity 管理外键与触发器。

【讨论】:

  • 当然,函数版本相当不完整,因为它不会阻止任何人在将行添加到tbl_two 后删除tbl_one 中的最后一行B
【解决方案2】:

如果您想要表 B 中字段 B 的外键,请删除字段 A、E 的主键,创建关系,然后将主键重置回这两个字段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    相关资源
    最近更新 更多