数据库包含外国密钥,即使存在外键约束,也没有存在的外键?

发布于 2025-01-31 23:33:09 字数 844 浏览 2 评论 0原文

我正在使用一个数据库,即即使存在外键约束,也没有外国密钥ID。

有一个名为“工作场所”的表格,带有一个名为“ advellyId”的外键列,指向另一个名为“地址”的表,

外键如下:

ALTER TABLE [dbo].[Workplace]  WITH NOCHECK ADD  CONSTRAINT [FK_Workplace_Address] FOREIGN KEY([AddressID])
REFERENCES [dbo].[Address] ([ID])
GO

ALTER TABLE [dbo].[Workplace] CHECK CONSTRAINT [FK_Workplace_Address]
GO

对于工作场所表中的一个特定行,地址ID的值为“ 1”。 。 当我运行时,从地址中选择 * ID = 1没有结果。

然后我运行更新Workplace SET addressID = 3其中workplace.id = 20值更改为3,我已验证是否存在具有ID 3的地址。

然后我运行更新Workplace SET ADDRESSID = 1其中workplace.id = 20再次获得错误

更新语句与外键约束“ fk_workplace_address”冲突。冲突发生在数据库db_name,表“ dbo.address”,列'id'。

我不明白的值1首先将其放在那里。在制定约束后,无法删除具有ID = 1的地址。如果首先删除了记录,则约束创建也将失败。有人知道这是怎么可能的吗?

这是Windows Server 2016上的数据库,SQL Server 12.0.4237.0

I am working with a database where there is a foreign key ID that doesn't exist even though there is a foreign key constraint.

There is a table called "Workplace" with a foreign key column called "AddressID" pointing to another table called "Address"

The foreign key is as follows:

ALTER TABLE [dbo].[Workplace]  WITH NOCHECK ADD  CONSTRAINT [FK_Workplace_Address] FOREIGN KEY([AddressID])
REFERENCES [dbo].[Address] ([ID])
GO

ALTER TABLE [dbo].[Workplace] CHECK CONSTRAINT [FK_Workplace_Address]
GO

For one particular row in the Workplace table, the AddressID has a value of "1".
When I run select * from Address where ID = 1 there is no result.

Then I ran update Workplace set AddressID = 3 where Workplace.ID = 20 the value changed to 3 and I have verified that an Address with ID 3 exists.

Then I ran update Workplace set AddressID = 1 where Workplace.ID = 20 again and I get the error

The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_Workplace_Address". The conflict occurred in database db_name, table "dbo.Address", column 'ID'.

I don't understand how the value 1 could have been put there in the first place. The Address with ID=1 couldn't have been deleted after the constraint was put in place. The constraint creation would also fail if the record was deleted in the first place. Does anyone know how this could be possible?

This is a database on Windows Server 2016, SQL Server 12.0.4237.0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清旖 2025-02-07 23:33:09

您可以使用nocheck创建forefer键,因此表中已经存在的值未检查。可以通过以下内容进行复制:

CREATE TABLE dbo.Address (ID int NOT NULL CONSTRAINT PK_Address PRIMARY KEY);
GO
CREATE TABLE dbo.Workplace (ID int NOT NULL CONSTRAINT PK_Workplace PRIMARY KEY,
                            AddressID int)
GO

INSERT INTO dbo.Workplace
VALUES(1,3); --Works
GO

ALTER TABLE dbo.WorkPlace  WITH NOCHECK ADD CONSTRAINT FK_Workplace_Address FOREIGN KEY (AddressID) REFERENCES dbo.Address(ID);
GO

ALTER TABLE dbo.Workplace CHECK CONSTRAINT FK_Workplace_Address;
GO

INSERT INTO dbo.Workplace
VALUES(2,3); --Fails
GO

UPDATE dbo.Workplace
SET AddressID = 2
WHERE ID = 1; --Fails
GO

DROP TABLE dbo.Workplace;
DROP TABLE dbo.Address;

如您所见,只有insert ed或UPDATE deption d 创建约束(使用nocheck)已验证;第一行插入 ED留在原样的情况下,并引用不存在的一行。

相反,创建没有noCheck定义的密钥,或使用检查,并且在尝试创建它时,该语句将失败:

CREATE TABLE dbo.Address (ID int NOT NULL CONSTRAINT PK_Address PRIMARY KEY);
GO
CREATE TABLE dbo.Workplace (ID int NOT NULL CONSTRAINT PK_Workplace PRIMARY KEY,
                            AddressID int)
GO

INSERT INTO dbo.Workplace
VALUES(1,3); --Works
GO

ALTER TABLE dbo.WorkPlace  WITH CHECK ADD CONSTRAINT FK_Workplace_Address FOREIGN KEY (AddressID) REFERENCES dbo.Address(ID); --Fails
GO
DROP TABLE dbo.Workplace;
DROP TABLE dbo.Address;

这将生成下面的错误:

Alter表语句与外键约束“ FK_Workplace_Address”冲突。冲突发生在数据库“沙箱”,表“ dbo.address”,列'id'。

或者,创建表时创建密钥;尽管现在可能为时已晚。

CREATE TABLE dbo.Address (ID int NOT NULL CONSTRAINT PK_Address PRIMARY KEY);
GO

CREATE TABLE dbo.Workplace (ID int NOT NULL CONSTRAINT PK_Workplace PRIMARY KEY,
                            AddressID int CONSTRAINT FK_Workplace_Address FOREIGN KEY REFERENCES dbo.Address(ID));
GO

INSERT INTO dbo.Workplace
VALUES(1,3); --Fails

GO

DROP TABLE dbo.Workplace;
DROP TABLE dbo.Address;

You create your FOREIGN KEY with NOCHECK, as a result the values that already exist in the table are not checked. This can be replicated with the following:

CREATE TABLE dbo.Address (ID int NOT NULL CONSTRAINT PK_Address PRIMARY KEY);
GO
CREATE TABLE dbo.Workplace (ID int NOT NULL CONSTRAINT PK_Workplace PRIMARY KEY,
                            AddressID int)
GO

INSERT INTO dbo.Workplace
VALUES(1,3); --Works
GO

ALTER TABLE dbo.WorkPlace  WITH NOCHECK ADD CONSTRAINT FK_Workplace_Address FOREIGN KEY (AddressID) REFERENCES dbo.Address(ID);
GO

ALTER TABLE dbo.Workplace CHECK CONSTRAINT FK_Workplace_Address;
GO

INSERT INTO dbo.Workplace
VALUES(2,3); --Fails
GO

UPDATE dbo.Workplace
SET AddressID = 2
WHERE ID = 1; --Fails
GO

DROP TABLE dbo.Workplace;
DROP TABLE dbo.Address;

As you can see, only rows that are INSERTed or UPDATEd after the constraint was created (with NOCHECK) are validated; the first row INSERTed is left as it was, with a reference to a row that does not exist.

Instead, create the key without NOCHECK defined, or with CHECK, and the statement will fail when you try to create it:

CREATE TABLE dbo.Address (ID int NOT NULL CONSTRAINT PK_Address PRIMARY KEY);
GO
CREATE TABLE dbo.Workplace (ID int NOT NULL CONSTRAINT PK_Workplace PRIMARY KEY,
                            AddressID int)
GO

INSERT INTO dbo.Workplace
VALUES(1,3); --Works
GO

ALTER TABLE dbo.WorkPlace  WITH CHECK ADD CONSTRAINT FK_Workplace_Address FOREIGN KEY (AddressID) REFERENCES dbo.Address(ID); --Fails
GO
DROP TABLE dbo.Workplace;
DROP TABLE dbo.Address;

This generates the error below:

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Workplace_Address". The conflict occurred in database "Sandbox", table "dbo.Address", column 'ID'.

Alternatively, create the key when you create the tables; though it's likely too late for that now.

CREATE TABLE dbo.Address (ID int NOT NULL CONSTRAINT PK_Address PRIMARY KEY);
GO

CREATE TABLE dbo.Workplace (ID int NOT NULL CONSTRAINT PK_Workplace PRIMARY KEY,
                            AddressID int CONSTRAINT FK_Workplace_Address FOREIGN KEY REFERENCES dbo.Address(ID));
GO

INSERT INTO dbo.Workplace
VALUES(1,3); --Fails

GO

DROP TABLE dbo.Workplace;
DROP TABLE dbo.Address;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文