sql delete cascade не работает - PullRequest
       24

sql delete cascade не работает

1 голос
/ 18 января 2011

У меня есть база данных Microsoft SQL с 2 таблицами: собака и кошка.

Таблица «собака» имеет столбец первичного ключа «еда», который также связан со столбцом «еда» в таблице «кошка», который действует как внешний ключ.

Связь между таблицами имеет набор правил "при удалении каскада", поэтому, когда я удаляю строку из таблицы "dog", соответствующие строки из таблицы "cat" также должны быть удалены.

Но строки в таблице "cat" не удаляются, они остаются. Я использую менеджер баз данных Microsoft SQL, чтобы удалить строку в таблице «dog».

Есть идеи, почему это происходит? мне нужно использовать специальную команду удаления 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

Ответы [ 6 ]

5 голосов
/ 19 января 2011

Я решил проблему.

В окне отношений была опция под названием Enforce Foreign Key Constraint, для которой было установлено значение «Нет». Я установил «Да», и теперь удаление строк работает хорошо.

4 голосов
/ 18 января 2011

Можете ли вы показать структуру вашей таблицы более конкретно?Звучит так, как будто вы неправильно используете PK / FK.

Удаление части FK (дочерней) ничего не делает для записи PK (родительской).Только когда вы удаляете записи PK, они каскадно связываются с дочерними записями, которые ссылаются на него.

1 голос
/ 19 марта 2017

Для людей, использующих 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])

Почему это произошло?

I , просто добавил ограничение и сразу получил ошибку внешнего ключа, потому что у меня были потерянные строки.Затем что-то запуталось, и он подумал, что каскад включен.

Поэтому, прежде чем создавать новое ограничение в пользовательском интерфейсе, я рекомендую всегда сначала проверять наличие потерянных строк.Вам все равно придется их удалить, если они существуют.

1 голос
/ 18 января 2011

Вы уверены, что столбец food в dog является первичным ключом dog?Если у вас есть таблица с именем food, то ее столбец food должен быть первичным ключом food и внешним ключом dogcat).Тогда при on delete cascade удалениях на food будут удалены соответствующие строки на dog и cat.

0 голосов
/ 18 января 2011

Это швы, чтобы работать просто отлично.

delete from Periods where PeriodID = 1

удалит одну строку из периодов и все строки из экзаменов с ExamPeriod = 1

0 голосов
/ 18 января 2011

Если таблица cat является ключом для внешнего ключа, то удаление строки из dog не приведет к удалению строки из cat, скорее это будет работать наоборот.

...