【问题标题】:Foreign Key constraint failure and error mesage when inserting values插入值时外键约束失败和错误消息
【发布时间】:2015-10-19 11:34:44
【问题描述】:

希望有人可以提供帮助。我创建了两个表 Customer 和 Order 如下;

CREATE TABLE Customer
CustomerID int NOT NULL PRIMARY KEY
CustomerName varchar(25)

客户表中的其他列与我的问题无关,因此我不会在此处包含它们。我的 CustomerID 编号从 1 到 15,都是唯一的。

我创建的第二个表是 Orders 如下

CREATE TABLE Orders
OrderID smallint NOT NULL PRIMARY KEY
OrderDate date NOT NULL
CustomerID int FOREIGN KEY REFERENCES Customer (CustomerID);

我的插入值如下

INSERT INTO Orders (OrderID, OrderDate, CustomerID)
VALUES
(1001, '2008-10-21', 1),
(1002, '2008-10-21', 8),
(1003, '2008-10-22', 15),
(1004, '2008-10-22', 5),
(1005, '2008-10-24', 3),
(1006, '2008-10-24', 2),
(1007, '2008-10-27', 11),
(1008, '2008-10-30', 12),
(1009, '2008-11-05', 4),
(1010, '2008-11-05', 1);

当我尝试将我的值插入 Order 表时,我收到以下错误消息......

消息 547,级别 16,状态 0,第 1 行.....INSERT 语句冲突 具有 FOREIGN KEY 约束“FK__OrderT__Customer__2D27B809”。这 发生冲突表“dbo.Customer”,列“CustomerID”。这 语句已终止。

我的 Order 表中 CustomerID 的数字是(1;1;2;3;4;5;8;11;12 和 15)。因此,我检查了我在 Order 表中的所有 CustomerID 编号也在 Customer 表中。

所以我的问题是

1) 插入值是否失败,因为我在 Customer 表中的 CustomerID 列在 NOT NULL 中并且我错误地将 CustomerID 列在 Order 中设置为 NULL。

2) 如果上述问题的答案是肯定的,那么我是否可以 (a) 在 Order 中的 CustomerID 列上删除外键 (b) 将该列更改为 NOT NULL 并且 (c) 然后添加再次对该列进行外键约束,然后再次插入值?

删除并重新创建表 Order 可能更容易。但我很好奇选项 2 是否可行,重新删除并在同一列上添加外键。

希望我认为错误发生的原因是正确的,感觉 如果我错了,请纠正我。

谢谢大家 乔西

【问题讨论】:

  • 什么值插入失败?
  • OrderT 还是 Orders?是错字吗?
  • @Abdul - 该表在 SQL 中称为 OrderT,我只是在这里将其称为 Order,所以这是一个错字,我指的是同一个表。
  • @Rowland 我现在已经在上面包含了我的插入值。必须插入失败的值必须是错误消息中提到的 Customer__2D27B809。但我不知道那会是哪个特定客户。我希望这会有所帮助。
  • 所以错误是您试图在 Orders 中插入任意 CustomerId 值 :) 您不需要更正 Customer 表中的值。它们并不意味着从 1 开始,也不意味着没有间隙。只需在订单中插入正确的 CustomerId 值。您不会真正使用手动编写的 CustomerId 值,而是从 Customer 表中选择它们,不是吗?

标签: sql-server


【解决方案1】:

1) 两者都不应为空。但是错误是因为您尝试插入不在 Customer 表中的 CustomerId。

2) 您可以简单地更改表并将其设为 NOT NULL(错误不是那个)。

示例:

CREATE TABLE Customer
  (
    CustomerID INT NOT NULL
                   PRIMARY KEY ,
    CustomerName VARCHAR(25)
  );

CREATE TABLE Orders
  (
    OrderID INT NOT NULL
                PRIMARY KEY ,
    OrderDate DATE NOT NULL ,
    CustomerID INT FOREIGN KEY REFERENCES Customer ( CustomerID )
  );

INSERT [Customer] ( [CustomerID], [CustomerName] )
VALUES  (   1, 'Customer 1' ),
(   2, 'Customer 2' ),
(   3, 'Customer 3' ),
(   4, 'Customer 4' ),
(   5, 'Customer 5' ),
(   6, 'Customer 6' );


INSERT [Orders] ( [OrderID], [OrderDate], [CustomerID] )
VALUES  
( 1, GETDATE(), 1 ),
( 2, GETDATE(), 2 ),
( 3, GETDATE(), 3 ),
( 4, GETDATE(), 4 ),
( 5, GETDATE(), 5 ),
( 6, GETDATE(), 6 );

INSERT [Orders] ( [OrderID], [OrderDate], [CustomerID] )
VALUES  ( 7, GETDATE(), 7 );

最后一个会出错,因为 CustomerID 为 7 的客户不存在。

更新:我后来看到了您的示例插入。您可以像这样找到有问题的 ID:

DECLARE @ids TABLE ( id INT );
INSERT  @ids ( [id] )
VALUES  ( 1 ),
        ( 8 ),
        ( 15 ),
        ( 5 ),
        ( 3 ),
        ( 2 ),
        ( 11 ),
        ( 12 ),
        ( 4 ),
        ( 1 );

SELECT  *
FROM    @ids AS [i]
WHERE   id NOT IN ( SELECT  CustomerID
                    FROM    [Customer] AS [c] );

【讨论】:

    【解决方案2】:

    1) 插入值是否失败,因为我的 CustomerID 列在 客户表在 NOT NULL 中,我错误地将 CustomerID 列设为 NULL 按顺序排列。

    没有。该错误与在 Order 表中允许 NULL 无关。 NULL 值将被允许但不检查引用完整性。

    外键违规错误意味着您试图将非 NULL CustomerID 值插入到 Customer 中不存在的 Order 表中。如果您确定存在 CustomerID 值,则列映射可能是错误的。尝试在 INSERT 语句中指定一个明确的列列表。

    【讨论】:

      【解决方案3】:

      当您尝试在外键列中插入一个值时会发生此错误,该值在其父表中不存在。例如,您尝试将值 X 插入 Order 表中的 CustomerId 中,该值在 Customer 表中不存在。发生此错误是因为我们需要有一个好的参照完整性策略。因此,您唯一需要做的就是检查您的新值(您要将它们插入到表中),以确定是否有任何值会损害此规则。

      但是,如果您想获得第二个问题的答案,可以尝试以下脚本:

      create table t1
      (
        Id int primary key,
        Name varchar(50) null
      )
      create table t2
      (
        Id int, 
        FK int null foreign key references t1(id)
      )
      
      go
      
      alter table t2
      alter column FK int not null
      

      【讨论】:

        猜你喜欢
        • 2011-10-04
        • 1970-01-01
        • 2016-06-04
        • 1970-01-01
        • 1970-01-01
        • 2012-07-18
        • 2021-12-28
        • 1970-01-01
        • 2015-09-08
        相关资源
        最近更新 更多