“表”中的列与现有主键或唯一约束不匹配

时间:2014-08-14 10:56:57

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

考虑两个数据库表tbl_One& tbl_Two

tbl_One的主要关键是:AB& E

tbl_Two的主要关键是:B& C

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

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

  

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

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:2)

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

如果你真的想为非主键创建一个外键,它必须是一个对它有唯一约束的列。

来自Books Online

  

FOREIGN KEY约束不必仅链接到PRIMARY   另一个表中的KEY约束;它也可以定义为参考   另一个表中UNIQUE约束的列。

在这种情况下,您需要tbl_One中的列B是唯一的,无论是作为主键还是对其具有唯一约束。

UNIQUE约束:

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

检查约束:

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

以下是展示此内容的SQL Fiddle

感谢您指出参考完整性问题Damien,AFTER DELETE触发器可以帮助解决这个问题,但是存在缺点。这是一个使用外键vs触发器管理的好discussion on referential integrity

答案 1 :(得分:1)

如果你想在表B中输入字段B的外键,删除字段A,E的主键,创建关系,然后将主键重置回这两个字段。