2010-10-28 3 views
1
CREATE Table A 
(
AId int , 
AName varchar(100) 
) 

CREATE Table B 
(
BId int, 
AId int, 
CId int, 
BName varchar(100) 
) 

CREATE Table C 
(
CId int, 
CName varchar (100) 

) 

«A» имеет внешний ключ в «B», а «C» также имеет внешний ключ в B. Оба внешних ключа имеют разрешение Cascade.Sql server 2005 - Cascade delete во всех связанных таблицах

Внешний ключ: -

/****** Object: ForeignKey [FK_B_A] Script Date: 10/28/2010 17:20:16 ******/ 
ALTER TABLE [dbo].[B] WITH CHECK ADD CONSTRAINT [FK_B_A] FOREIGN KEY([AId]) 
REFERENCES [dbo].[A] ([AId]) 
ON DELETE CASCADE 
GO 
ALTER TABLE [dbo].[B] CHECK CONSTRAINT [FK_B_A] 
GO 
/****** Object: ForeignKey [FK_B_C] Script Date: 10/28/2010 17:20:16 ******/ 
ALTER TABLE [dbo].[B] WITH CHECK ADD CONSTRAINT [FK_B_C] FOREIGN KEY([CId]) 
REFERENCES [dbo].[C] ([CId]) 
ON DELETE CASCADE 
GO 
ALTER TABLE [dbo].[B] CHECK CONSTRAINT [FK_B_C] 
GO 

- Выборочные данные

INSERT INTO A 
VALUES (1, 'Ashish') 
INSERT INTO A 
VALUES (2, 'Sanjay') 
INSERT INTO A 
VALUES (3, 'Vivek') 

INSERT INTO B 
VALUES 
(1,1,10,'Ashish1') 
INSERT INTO B 
VALUES 
(2,1,11,'Ashish2') 
INSERT INTO B 
VALUES 
(3,1,12,'Ashish3') 


INSERT INTO B 
VALUES 
(4,2,13,'Ashish1') 
INSERT INTO B 
VALUES 
(5,2,14,'Sanjay') 
INSERT INTO B 
VALUES 
(6,3,15,'Vivek') 

INSERT INTO C 
VALUES 
(10, 'Ashish Data1') 
INSERT INTO C 
VALUES 
(11, 'Ashish Data2') 

INSERT INTO C 
VALUES 
(12, 'Ashish Data3') 

INSERT INTO C 
VALUES 
(13, 'Ashish Data4') 

INSERT INTO C 
VALUES 
(14, 'sanjay Data1') 

INSERT INTO C 
VALUES 
(15, 'Vivek Data1') 

Я думал, следующие будут удалены все данные из всех таблиц: -

DELETE a FROM A a 
INNER JOIN B ON A.AId = B.AId 
INNER JOIN C ON B.CId = C.CID 

вместо я должен был напишите это: -

DELETE a FROM A a 
INNER JOIN B ON A.AId = B.AId 

DELETE b FROM B b 
INNER JOIN C ON B.CId = C.CID 

Есть ли способ удалить все данные в единую инструкцию удаления?

+0

Пожалуйста, пост определения вашего 'Foregin KEYs' – Quassnoi

+0

@Quassnoi, размещены определения внешних ключей. –

ответ

0

Вы не можете удалить записи из A и C с помощью одного оператора, потому что эти таблицы не находятся в переходном эталонном отношении.

Если вы хотите удалить все записи из A и C, которые имеют соответствующие записи в B, вы должны использовать два заявления:

DELETE a 
FROM a 
JOIN b 
ON  b.aid = a.aid 

DELETE c 
FROM c 
JOIN b 
ON  b.cid = c.cid 
+0

Я не думаю, что соединение необходимо. Ограничение внешнего ключа будет гарантировать, что данные в B связаны с данными в A. Ну, соединение потребуется только в том случае, если вы хотите удалить все записи в A и B, кроме строк в A, которые не указаны в B. – pavanred

+0

@ Паван: как я уже сказал, этот запрос удаляет «все записи из' A' и 'C', которые имеют соответствующие записи в' B' ' – Quassnoi

1

В принципе, если я правильно понял, вы можете удалять только данные из «b» и удалять данные в «a» и «c».

< - B [удалить] -> С

От Microsoft website:

ON DELETE CASCADE

Указывает, что если предпринимается попытка удалить строку с ключ, на который ссылаются внешние ключи в существующих строках в других таблицах, также удаляются все строки, содержащие эти внешние ключи. Если каскадные ссылочные действия также были определены в целевых таблицах, указанные каскадные действия также выполняются для строк, удаленных из этих таблиц.

+0

Нет, удаление данных с C не удаляет данные из A и B. –

+1

Просто пытаюсь обойти его, но я думаю, что вы ответили на эту проблему, но это потому, что FK являются A-> B <-C - или что-то в этом роде, которое останавливает каскад. –

+0

Не работает также: - УДАЛИТЬ ОТ ОТ C c ВХОДЯЩИЙ ПРИСОЕДИНЕНИЕ B НА C.CId = B.CId INNER JOIN A ON A.AId = B.AId –

1

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

Так что в вашем случае таблицы B является дочерней таблице как для таблицы А и таблицы С.

Таким образом, вы не можете иметь один ВЕЬЕТЕ удалить данные из всех таблиц. Вместо этого, вы можете удалить строку из таблицы А и удалит соответствующие дочерние строки из таблицы B.

Аналогично, удалить из таблицы C удалит его соответствующие дочерние строки из таблицы B.

Edit - THe Запросы, которые вы написали, удаляются без предложения where. Так что, если вы пытаетесь удалить все строки из таблицы А и таблицы C и там, удалив все ссылки строки в таблице B, вы можете использовать это -

DELETE FROM A --deletes all rows in A and corresponding referenced rows in B 

DELETE FROM C --deletes all rows in C and corresponding referenced rows in B 
+0

Да, правильно. Подобно операторам удаления, которые у меня уже есть в моем вопросе. –

+0

Добавил сообщения о удалении в мой ответ – pavanred

0

Хм, можно ли изменить ограничение?

Проблема, поскольку я вижу, что C имеет от 1 до многих с A, а B имеет от 1 до многих с C, поэтому вместо того, чтобы иметь AId быть внешним ключом в B, есть AId - это внешний ключ в C, Итак, если вы удалите человека из A, он будет каскадом до C, который будет каскадом к B. Если вы удалите элемент из C, он будет каскадом к B, но не A, и если вы удалите элемент из B, он не будет влиять ни на одну из двух других таблиц.

Мое предложение:

CREATE TABLE [A] (
    [AId] [int] NOT NULL , 
    [AName] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL , 
    CONSTRAINT [PK_A] PRIMARY KEY CLUSTERED 
    (
     [AId] 
    ) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

CREATE TABLE [C] (
    [CId] [int] NOT NULL , 
    [CName] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL , 
    [AId] [int] NULL , 
    CONSTRAINT [PK_C] PRIMARY KEY CLUSTERED 
    (
     [CId] 
    ) ON [PRIMARY] , 
    CONSTRAINT [FK_C_A] FOREIGN KEY 
    (
     [AId] 
    ) REFERENCES [A] (
     [AId] 
    ) ON DELETE CASCADE 
) ON [PRIMARY] 
GO 

CREATE TABLE [B] (
    [BId] [int] NOT NULL , 
    [AId] [int] NULL , 
    [CId] [int] NULL , 
    [BName] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL , 
    CONSTRAINT [PK_B] PRIMARY KEY CLUSTERED 
    (
     [BId] 
    ) ON [PRIMARY] , 
    CONSTRAINT [FK_B_C] FOREIGN KEY 
    (
     [CId] 
    ) REFERENCES [C] (
     [CId] 
    ) ON DELETE CASCADE NOT FOR REPLICATION 
) ON [PRIMARY] 
GO 

С помощью этой установки, Delete From A вычистит все 3 таблицы на одном дыхании.

Редактировать: вы можете сохранить AId в B, чтобы упростить объединение, но это не будет иметь никакого отношения к каскаду удаления.

Смежные вопросы