Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 '中的列;表';与现有主键或唯一约束不匹配_Sql Server 2008_Tsql_Foreign Key Relationship - Fatal编程技术网

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
中的最后一行。