2016-01-18 3 views
0

У меня есть три таблицы - группы, концерты и правопреемникиКак удалить запись, учетные записи и записи внуков?

Таблица (который присваивает гиг для зарегистрированного пользователя, который вошел в него, чтобы создать много-много отношений между концертами и пользователями.):

Bands: bandID, bandname 
Gigs: GigID, bandID, venue, date 
Assigns: assignID, gigid, userid (which is then linked to the users table) 

Функция на сайте - удалить группу, но затем она «О, прежде чем вы удалите группу, она удалит все эти концерты», тогда пользователь выбирает подтверждение и так далее.

Мне нужен запрос, который удаляет группу, а затем удаляет концерты, где gigs.bandID = bands.bandID, а затем удаляет назначения, где assigns.gigID = gigs.gigID.

Я разработал инструкцию SELECT, и это отображает запись, которую я хочу удалить из таблицы назначений, подав ей бандад.

SELECT assigns.* 
FROM bands INNER JOIN 
    gigs ON bands.bandid = gigs.bandid INNER JOIN 
    gigsaccass ON gigs.gigid = gigsaccass.gigid AND bands.bandid = 91 

Но как мне создать инструкцию DELETE?

+2

Вы говорите о каскадном удалении По умолчанию каскадное удаление отключено на dbs, вам нужно установить каскадное удаление на эти внешние ключи, чтобы при удалении родительской записи они будут автоматически удалены. вам не нужно писать отдельные инструкции удаления для записей детей и внуков. – jae555

+2

Операция удаления может влиять только на одну таблицу. Чтобы удалить из всех трех уровней без нарушения ограничений, вам необходимо (a) удалить из внуков, используя соединение из трех таблиц ('delete gc from grandchild as gc join child как c join parent как p'), (b) delete from children, используя соединение из двух таблиц ('delete c from child as c join parent as p'), затем (c) удалить из родителя. –

+0

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

ответ

2

Есть куча способов, которыми Вы могли бы пойти об этом, но это маршрут я бы идти, если вы не хотите, чтобы сделать выбор ON DELETE CASCADE ограничение ...

Declare @bandID Int 
Set  @bandID = 91 

--  Delete the associated gigsaccess records 
DELETE ga 
FROM bands As b 
INNER JOIN gigs As g 
     ON b.bandid = g.bandid 
INNER JOIN gigsaccass As ga 
     ON g.gigid = ga.gigid 
WHERE b.bandid = @bandID 

--  Delete the associated gigs records 
DELETE g 
FROM bands As b 
INNER JOIN gigs As g 
     ON b.bandid = g.bandid 
WHERE b.bandid = @bandID 

--  Delete the band record 
DELETE b 
FROM bands As b 
WHERE b.bandid = @bandID 
+1

И если вы хотите, чтобы это была операция «все или ничего», заверните все удаленные транзакции. –

+0

Приветствия, это место на. :) –

0

Как говорит jae555, я бы сказал, что триггер ON DELETE CASCADE - это путь.

2

Существует два способа, которым это можно сделать: один, как уже упоминалось, является Cascading Delete. Другим было бы эффективно воссоздать каскадное удаление с помощью нескольких запросов. Лично я предпочитаю второй вариант, так как он позволяет вам немного больше контролировать ваши данные. Использование каскадных удалений (особенно в производственной среде) может привести к довольно катастрофическим последствиям, если вы не будете очень осторожны. Отмена удаления одной записи может быть довольно простой (если это простая таблица), уничтожение каскадного удаления, которое непреднамеренно ударяет по 20 различным таблицам, практически невозможно без резервного копирования базы данных.

+0

Никогда не забывайте, что: использование каскадных удалений может привести к довольно катастрофическим последствиям, если вы не будете очень осторожны. –

+0

Как было упомянуто в комментариях к основному сообщению, это отключено по умолчанию для большинства (всех?) СУБД. Для этого есть веская причина ... – user2366842

0

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

-- foreign key constraint 
ALTER TABLE [dbo].[Gigs] WITH CHECK 
ADD CONSTRAINT [FK_Gigs_Band] FOREIGN KEY([BandID]) 
REFERENCES [dbo].[Bands] ([BandID]) 
ON DELETE CASCADE 
GO 

-- foreign key constraint 
ALTER TABLE [dbo].[Assigns] WITH CHECK 
ADD CONSTRAINT [FK_Assigns_Gigs] FOREIGN KEY([GigID]) 
REFERENCES [dbo].[Gigs] ([GigID]) 
ON DELETE CASCADE 
GO 

убедитесь, что вы удалите текущий внешний ключ первым, если у вас есть один ..

другой способ создания триггеров .. в частности, Instead of Delete вызывает

CREATE TRIGGER [DELETE_Bands] 
    ON dbo.[Bands] 
    INSTEAD OF DELETE 
AS 
BEGIN 
SET NOCOUNT ON; 
DELETE FROM [Gigs] WHERE BandID IN (SELECT BandID FROM DELETED) 
DELETE FROM [Bands] WHERE BandID IN (SELECT BandID FROM DELETED) 
END 
GO 

CREATE TRIGGER [DELETE_Gigs] 
    ON dbo.[Gigs] 
    INSTEAD OF DELETE 
AS 
BEGIN 
SET NOCOUNT ON; 
DELETE FROM [Assigns] WHERE GigID IN (SELECT GigID FROM DELETED) 
DELETE FROM [Gigs] WHERE GigID IN (SELECT GigID FROM DELETED) 
END 
GO 
Смежные вопросы