【问题标题】:How do I do referential integrity in SQL Server with a compound key?如何使用复合键在 SQL Server 中执行参照完整性?
【发布时间】:2015-12-02 04:40:16
【问题描述】:

运行底部看到的SQL,为什么会返回:

消息 1776,第 16 级,状态 0,第 2 行
引用表 'priceex.table_a' 中没有与外键 'FK_delete_from_parent' 中的引用列列表匹配的主键或候选键。

消息 1750,第 16 级,状态 0,第 2 行
无法创建约束。查看以前的错误。

代码:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE table_a 
(
    [column_1] [int] NULL,
    [column_2] [int] NULL
)

CREATE TABLE table_b 
(
    [column_1] [int] NULL,
    [column_2] [int] NULL
)

GO

CREATE NONCLUSTERED INDEX IX_app ON table_a (column_1, column_2)
GO

CREATE NONCLUSTERED INDEX IX_app ON table_b (column_1, column_2)
GO

SET ANSI_PADDING OFF
GO

ALTER TABLE table_b WITH CHECK
ADD CONSTRAINT FK_delete_from_parent 
    FOREIGN KEY (column_1, column_2) REFERENCES table_a (column_1, column_2) 
       ON DELETE CASCADE
GO

【问题讨论】:

  • 您的表没有主键。您创建了一个非聚集索引,但这与主键不同。为 column_1、column_2 向表中添加主键,它将起作用。
  • 我知道如果我创建一个唯一索引(但不创建任何主键),同样会起作用。哪些“类型”的索引是主键和唯一索引,它们的行为与索引不同?
  • SQL Server 无法在可为空的字段上创建主键。在列定义中用 NOT NULL 替换 NULL 会有所帮助。
  • @DeveloperWebs 不确定您的意思。主键不是一种索引。默认情况下,如果表上还没有聚集索引,那么它将是一个聚集索引,在这种情况下,它将是一个非聚集索引。唯一索引只是表明该索引可以防止重复值。
  • @Frisbee 主键不是索引。这是一个不允许 null 的约束。将在 sql server 中为具有主键约束的列自动创建索引。 msdn.microsoft.com/en-us/library/ms189039.aspx

标签: sql sql-server tsql


【解决方案1】:

您需要将PRIMARY KEY添加到table_a并将PK的列更改为NOT NULL

CREATE TABLE table_a (
    [column_1] [int] NOT NULL,
    [column_2] [int] NOT NULL,
    PRIMARY KEY(column_1, column_2)            -- compound primary key
);

CREATE TABLE table_b (
    [column_pk] [int] NOT NULL PRIMARY KEY,    -- you probably want different pk
    [column_1] [int] NULL,
    [column_2] [int] NULL
);

-- adding foreign key constraint
ALTER TABLE table_b WITH CHECK
ADD CONSTRAINT FK_delete_from_parent FOREIGN KEY (column_1, column_2)
REFERENCES table_a (column_1, column_2) ON DELETE CASCADE;

SqlFiddleDemo

编辑:

Create Foreign Key Relationships:

外键约束不必仅链接到主键 另一个表中的键约束;也可以定义为引用 另一个表中的唯一约束的列

CREATE TABLE table_a (
    [column_1] [int] NOT NULL,           -- with UNIQUE column can be nullable
    [column_2] [int] NOT NULL,
    UNIQUE(column_1, column_2)
    -- anyway this table should have PK
);

SqlFiddleDemo2

请注意,如果列可以为空并且您有 NULLON DELETE CASCADE 将不会从相应的表中删除记录。

【讨论】:

  • 嗯,一个主键或一个唯一索引。我猜需要一个强制唯一值的索引。
  • @DeveloperWebs 一个唯一的可以是空的,但它仍然必须是唯一的——你不能有多个空,空
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
相关资源
最近更新 更多