Я просто ответил another question где этот вопрос был связан как дубликат. Я думаю, что стоит поместить мой ответ и здесь:
Это невозможно. Вы можете решить эту проблему с помощью INSTEAD OF TRIGGER
create table locations
(
id int identity(1, 1),
name varchar(255) not null,
parent_id int,
constraint pk__locations
primary key clustered (id)
)
GO
INSERT INTO locations(name,parent_id) VALUES
('world',null)
,('Europe',1)
,('Asia',1)
,('France',2)
,('Paris',4)
,('Lyon',4);
GO
триггера --This будет использовать рекурсивный КТР, чтобы получить все идентификаторы следующих все идентификаторы, которые Вы удаляете. Эти идентификаторы удаляются.
CREATE TRIGGER dbo.DeleteCascadeLocations ON locations
INSTEAD OF DELETE
AS
BEGIN
WITH recCTE AS
(
SELECT id,parent_id
FROM deleted
UNION ALL
SELECT nxt.id,nxt.parent_id
FROM recCTE AS prv
INNER JOIN locations AS nxt ON nxt.parent_id=prv.id
)
DELETE FROM locations WHERE id IN(SELECT id FROM recCTE);
END
GO
- Попробуйте его здесь, попробуйте с разными идентификаторами. Вы можете попробовать WHERE id IN(4,3)
также ...
SELECT * FROM locations;
DELETE FROM locations WHERE id=4;
SELECT * FROM locations
GO
--clean-Up (CAREFULL с реальными данными!)
if exists(select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME='locations')
---DROP TABLE locations;
PostgreSQL поддерживает его. Теперь, если другая запись, которая не должна быть удалена, ссылается на сущность, которая должна быть удалена, она выдаст ошибку, и операция удаления будет отменена. В противном случае он будет работать отлично. Реальная проблема заключается в том, является ли ваше отношение parent-child нециклическим ориентированным графом или нет. Поскольку большинство самоидентификаций реализуют иерархии, а иерархии должны быть направлены нециклическими графами, в большинстве случаев курс действий PostgreSQL будет более разумным. Во всех остальных случаях вы все равно можете реализовать эту функцию вручную, поэтому ничего не потеряно. –