0

One table has the name "Stages", every Stage can have 0 to infinity children. In the table "Stages" there is a column named "Parent". This column is foreign a key for the same table "Stages".

How would I make a cascading delete for this tree? I want to when deleting any row in this table, automatically delete all their children and their children's children...

With the following query

GO
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Stage_Stage]') AND parent_object_id = OBJECT_ID(N'[dbo].[Stage]'))
ALTER TABLE [dbo].[Stage]  WITH CHECK ADD  CONSTRAINT [FK_Stage_Stage] FOREIGN KEY([parent])
REFERENCES [dbo].[Stage] ([id]) ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Stage] CHECK CONSTRAINT [FK_Stage_Stage]
GO

I get this error

Msg 1785, Level 16, State 0, Line 2
Introducing FOREIGN KEY constraint 'FK_Stage_Stage' on table 'Stage' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Msg 1750, Level 16, State 0, Line 2
Could not create constraint. See previous errors.
Msg 4917, Level 16, State 0, Line 1
Constraint 'FK_Stage_Stage' does not exist.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Dmitriy Kudinov
  • 1,051
  • 5
  • 23
  • 31

1 Answers1

1

Add foreigns key with ON DELETE CASCADE option for all "child" tables.

ALTER TABLE SomeChildTable 
CONSTRAINT YOurConstraintName 
FOREIGN KEY (YourParentId)
REFERENCES YourParentTable(ParentTableId) ON DELETE CASCADE;

for new tables:

CREATE TABLE ttt
(
  ...
  CONSTRAINT YOurConstraintName 
  FOREIGN KEY (YourParentId)
  REFERENCES YourParentTable(ParentTableId) ON DELETE CASCADE
)
Michael Pakhantsov
  • 24,855
  • 6
  • 60
  • 59
  • This works only on distinguish tables. When table link on itself this not work – Dmitriy Kudinov Aug 05 '10 at 15:47
  • @Evl-ntnt, its works for tables which have link to itself. May you provide information what you did, and what is exactly does not works? – Michael Pakhantsov Aug 05 '10 at 16:00
  • I read that not works on sql.ru tomorrow I will try it again and message you thanx – Dmitriy Kudinov Aug 05 '10 at 18:46
  • Я наверное непонятно написал на английском. В общем в моей БД есть таблица в которой хранятся этапы разработки. Логически один этап может разбиваться на другие этапы, в БД это реализовано с помощью поля "родитель" - которое ссылается на другую запись в этой таблице. Так вот. Хочу что бы при удалении одной записи удалялись все записи у которых в поле родитель - удаляемая запись (логически - удаляются потомки удаляемой записи). Прочитал что одном форуме что каскадное удаление действует только на разные таблицы. Вот тут прочитал http://www.sql.ru/Forum/actualthread.aspx?bid=6&tid=630450&hl= – Dmitriy Kudinov Aug 05 '10 at 18:57
  • Я проверил в Oracle там всё работает. Реально вся цепь удаляется каскадом. Завтра проверю в mssql. Отпишусь. на sql.ru речь о mysql – Michael Pakhantsov Aug 05 '10 at 19:40
  • Обновил самый первый пост. Видимо действительно нельзя использовать каскадное удаление при рекурсии. Может триггер можно написать какой нибудь? – Dmitriy Kudinov Aug 06 '10 at 06:08
  • 1
    Глянь сюда http://stackoverflow.com/questions/1783700/sql-server-self-reference-fk-trigger-instead-of-on-delete-cascade – Michael Pakhantsov Aug 06 '10 at 07:14
  • Спасибо. Если отредактируешь свой первый ответ то я смогу плюсик поставить – Dmitriy Kudinov Aug 06 '10 at 10:01