我有一个带有2个表的Microsoft SQL数据库:dog and cat。
“dog”表有一个名为“food”的主键列,它与“cat”表中的一个名为“food”的列相关,该表用作外键。
表之间的关系有一个“on delete cascade”规则集,所以当我从“dog”表中删除一行时,“cat”表中的重定义行也应该被删除。
但是“cat”表中的行会删除net,它们会保留。我使用Microsoft SQL数据库管理器删除“dog”表中的行。
知道为什么会这样吗?我是否需要使用特殊的delete sql命令以这种方式删除行?
//修改
表格的脚本是:
USE [VELES]
GO
/****** Object: Table [dbo].[Periods] Script Date: 01/18/2011 14:52:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Periods](
[PeriodID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[PeriodName] [nvarchar](50) COLLATE Hebrew_CS_AS NULL,
[PeriodStartDate] [smalldatetime] NOT NULL,
[PeriodEndDate] [smalldatetime] NOT NULL,
CONSTRAINT [PK_Periods] PRIMARY KEY CLUSTERED
(
[PeriodID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
USE [VELES]
GO
/****** Object: Table [dbo].[Exams] Script Date: 01/18/2011 14:55:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Exams](
[ExamID] [int] IDENTITY(1,1) NOT NULL,
[ExamUserID] [char](7) COLLATE Hebrew_CS_AS NOT NULL,
[ExamBase] [tinyint] NOT NULL,
[ExamUserTimesAccessed] [tinyint] NULL,
[ExamMaxTimesToOpen] [tinyint] NOT NULL,
[ExamUserLastTimeOpened] [datetime] NULL,
[ExamUserLastTimeFinished] [datetime] NULL,
[ExamTimeToFinish] [int] NOT NULL,
[ExamPassGrade] [int] NOT NULL,
[ExamPeriod] [int] NOT NULL,
[ExamUserRank] [tinyint] NULL,
CONSTRAINT [PK_Exams] PRIMARY KEY CLUSTERED
(
[ExamID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [VELES]
GO
ALTER TABLE [dbo].[Exams] WITH CHECK ADD CONSTRAINT [FK_Exams_Bases] FOREIGN KEY([ExamBase])
REFERENCES [dbo].[Bases] ([BaseID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Exams] WITH NOCHECK ADD CONSTRAINT [FK_Exams_Periods] FOREIGN KEY([ExamPeriod])
REFERENCES [dbo].[Periods] ([PeriodID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Exams] WITH NOCHECK ADD CONSTRAINT [FK_Exams_Users] FOREIGN KEY([ExamUserID])
REFERENCES [dbo].[Users] ([UserID])
ON UPDATE CASCADE
ON DELETE CASCADE
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[Exams] CHECK CONSTRAINT [FK_Exams_Users]
GO
ALTER TABLE [dbo].[Exams] WITH CHECK ADD CONSTRAINT [UserRanks_Exams_FK1] FOREIGN KEY([ExamUserRank])
REFERENCES [dbo].[UserRanks] ([RankID])
ON UPDATE CASCADE
ON DELETE CASCADE
答案 0 :(得分:5)
我已经解决了这个问题。
在关系窗口中,有一个名为Enforce Foreign Key Constraint
的选项,设置为“否”。
我将其设置为“是”,现在行删除效果很好。
答案 1 :(得分:4)
你能更具体地展示你的桌面结构吗? 这听起来像PK / FK错误的方式。
删除FK部分(子)不会对PK记录(父级)执行任何操作。 只有当您删除PK记录时,它才会级联到链接到它的子记录。
答案 2 :(得分:1)
您确定food
中的dog
列是dog
的主键吗?如果您有一个名为food
的表,那么它的列food
应该是food
的主键和dog
的外键(以及cat
)。然后,on delete cascade
上的food
次删除会导致dog
和cat
上的相应行被删除。
答案 3 :(得分:1)
对于使用SQL Server Management Studio的人员:
我确实看到过用户界面与数据库不同步的情况,即使您刷新了密钥列表或打开了一个全新的实例。
对于我的情况,我有一个Order
,其中有DiscountedItem
个子项目。
检查相关内容是否不同步的方法是右键单击FK_DiscountedItem_Order
并选择Script Key as CREATE To Clipboard
,然后检查您获得的内容:
你应得到这样的东西:
ALTER TABLE [dbo].[DiscountedItem] WITH NOCHECK ADD CONSTRAINT [FK_DiscountedItem_Order] FOREIGN KEY([OrderId])
REFERENCES [dbo].[Order] ([OrderId])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[DiscountedItem] CHECK CONSTRAINT [FK_DiscountedItem_Order]
GO
您可以清楚地看到DELETE CASCADE
。
如果您得到类似以下内容的内容,那么尽管用户界面可能会说出来,但级联规则实际上并不活跃:
ALTER TABLE [dbo].[DiscountedItem] WITH CHECK ADD CONSTRAINT [FK_DiscountedItem_Order] FOREIGN KEY([OrderId])
REFERENCES [dbo].[Order] ([OrderId])
GO
我刚删除它(必须实际删除它两次)并重新创建它以获得正确的SQL。
你可能需要运行这样的东西来检查“孤儿”这样的事情。子行:
select * from DiscountedItem where DiscountedItem.orderid not in (select orderid from [order])
然后如果这样做是安全的:
delete from DiscountedItem where DiscountedItem.orderid not in (select orderid from [order])
为什么会这样?
我只是添加了约束并立即得到了外键错误,因为我有孤立的行。然后有些东西感到困惑,并认为级联已启用。
因此,在UI中创建新约束之前,我建议您始终先检查孤立行。如果它们存在,你将不得不删除它们。
答案 4 :(得分:0)
如果cat表是外键的键,那么从dog中删除一行不会从cat中删除一行,而是反过来。
答案 5 :(得分:0)
这种接缝工作得很好。
delete from Periods where PeriodID = 1
将从句点中删除一行,并从具有ExamPeriod = 1
的考试中删除所有行