acabo respondió another question donde esta pregunta estaba obligado como duplicado. Creo que también vale la pena colocar mi respuesta aquí:
Esto no es posible. Puede resolver esto con un 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
--Este gatillo utilizará un CTE recursiva para obtener todos los ID siguientes todos los identificadores que está eliminando. Estas identificaciones se eliminan.
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
- Pruébalo aquí, prueba con diferentes ID. Usted puede tratar de WHERE id IN(4,3)
también ...
SELECT * FROM locations;
DELETE FROM locations WHERE id=4;
SELECT * FROM locations
GO
--clean-Up (Carefull con datos reales!)
if exists(select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME='locations')
---DROP TABLE locations;
PostgreSQL lo soporta. Ahora, si otra entrada que no se va a eliminar hace referencia a una subinserción que se va a eliminar, emitirá un error y la operación de eliminación se revertirá. De lo contrario, funcionará perfectamente. El verdadero problema es si su relación padre-hijo es un gráfico dirigido no cíclico o no. Debido a que la mayoría de las autorreferencias implementan jerarquías, y las jerarquías deben dirigirse a gráficos no cíclicos, el curso de acción de PostgreSQL seguramente será más sensato en la mayoría de los casos. En todos los demás casos, puede implementar esa funcionalidad de forma manual, para que no se pierda nada. –