【问题标题】:FOREIGN KEY constraint error on insert even though entry already exists即使条目已经存在,插入时的 FOREIGN KEY 约束错误
【发布时间】:2013-11-08 23:46:23
【问题描述】:

我创建了两个表,Customers 和 Records。 Records 对 customerID 有一个外键约束。当我尝试向已经存在的客户插入记录时,它给了我这个错误:

  Message (The INSERT statement conflicted with the FOREIGN KEY constraint "FK_REC_cstmr_int_id". The conflict occurred in database "Omitted", table "dbo.CST_NEW_CUSTOMER", column 'cstmr_int_id'.)

这里是插入代码:

INSERT INTO [Omitted].[dbo].[REC_NEW_RECORDS]
       ([cstmr_int_id]
       ,[xml_tx]
VALUES
       (10
       ,'<test>test</test>'
GO

我在这里找到的大多数相关问题都涉及以错误的顺序插入,但我可以选择 id 为 10 的客户。任何指针将不胜感激。

编辑 1:这将返回一位客户

SELECT [cstmr_int_id]
   FROM [Omitted].[dbo].[CST_NEW_CUSTOMER] WHERE cstmr_int_id =10

编辑 2:这是记录表的创建脚本

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[REC_NEW_RECORDS](
[rec_int_id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[cstmr_int_id] [int] NOT NULL,
[xml_tx] [varchar](max) NULL,
CONSTRAINT [REC_PK_rec_int_id] PRIMARY KEY CLUSTERED 
(
[rec_int_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[REC_NEW_RECORDS]  WITH CHECK ADD  CONSTRAINT [FK_REC_cstmr_int_id] FOREIGN KEY([cstmr_int_id])
REFERENCES [dbo].[CST_NEW_CUSTOMER] ([cstmr_int_id])
GO

【问题讨论】:

  • 你是说dbo.cst_new_customer10的记录,SQL Server喝醉了?
  • 我建议再次仔细查看该 FK 的代码。只有当 PK 表中没有 ID 为 10 的记录时,才会出现该错误。确保 FK 确实按照您认为的方式构建,并且父表中的 ID 确实存在。
  • 但是您的错误表明 cstmr_int_id 列上的 dbo.CST_NEW_CUSTOMERdbo.REC_NEW_RECORDS 之间存在 FK 关系。如果你写了SELECT * FROM dbo.CST_NEW_CUSTOMER C WHERE C.cstmr_int_id = 10,你会得到结果吗?
  • ALTER TABLE [dbo].[REC_NEW_RECORDS] WITH CHECK ADD CONSTRAINT [FK_REC_cstmr_int_id] FOREIGN KEY([cstmr_int_id]) REFERENCES [dbo].[CST_NEW_CUSTOMER] ([cstmr_int_id]) REC_NEW_RECORDS 之前,指定的cstmr_int_id 必须 已经存在于CST_NEW_CUSTOMER 中。由于您的约束指定了 WITH CHECK,这意味着它是有效的(如果您禁用它,它会被标记为不受信任并允许您违反 RI)。这是按预期工作的关系完整性。
  • 当您清理代码以使其对这些受众更友好时,也许在您的清理过程中您已经设法修复了任何损坏的地方。使用TCO514 之类的表名,这很容易做到

标签: sql sql-server sql-server-2008


【解决方案1】:

引用的表中不存在该值。这是您引用的表中没有10 的场景:

设置

create table cst_new_customer (
  cstmr_int_id int not null primary key);

insert into cst_new_customer (cstmr_int_id) values (9), (11);

create table rec_new_records (
  cstmr_int_id int not null primary key,
  xml_tx varchar(50));

alter table rec_new_records add constraint fk_rec_cstmr_int_id
foreign key (cstmr_int_id) references cst_new_customer (cstmr_int_id);

测试 1

insert into rec_new_records values (10, 'test');

结果

INSERT 语句与 FOREIGN KEY 约束“fk_rec_cstmr_int_id”冲突。冲突发生在数据库“db_3_055da”、表“dbo.cst_new_customer”、列“cstmr_int_id”中。:

测试 2

insert into rec_new_records values (11, 'test');

结果

| CSTMR_INT_ID | XML_TX | |--------------|--------| | 11 |测试 |

See a demo

【讨论】:

  • id 为 10 的客户虽然存在于数据库中
  • 嗯,它没有。 SELECT * FROM dbo.CST_NEW_CUSTOMER C WHERE C.cstmr_int_id = 10 的结果是什么?
  • 您可以尝试删除约束并重新添加吗?
【解决方案2】:

您是否对上述所有查询/语句使用相同的连接?

问题可能只是与未提交的事务有关。

【讨论】:

  • 我该如何检查这个?
  • SELECT er.session_id, er.open_transaction_count FROM sys.dm_exec_requests er Where open_transaction_count &gt; 0
  • 它与未提交的事务有关。也感谢 Love2Learn!
  • @Bishop - 外键查找不会读取未提交的数据。未提交的事务会导致阻塞而不是虚假错误。
  • 我不确定是什么原因造成的,后来又是什么解决的。当我在时,还有另一个人在同一个数据库上工作。也许与此有关。
【解决方案3】:

我今天遇到的这个问题的一个可能场景是我有两个外键约束。我只在引用的表中插入了其中一个,但我不知道没有插入的第二个外键约束。

【讨论】:

    猜你喜欢
    • 2019-10-05
    • 2014-03-20
    • 1970-01-01
    • 2023-03-22
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多