Организирането на правилни каскадни изтривания е мъдро и обикновено е правилното решение за това. За някои специални случаи има друго решение за това, което може да бъде подходящо.
Ако трябва да извършите множество изтривания въз основа на общ набор от данни, можете да използвате Общи таблични изрази (CTE) .
Трудно е да се измисли прост пример, тъй като основният случай на употреба за това може да бъде покрит от каскадни изтривания.
За примера ще изтрием всички елементи в таблица A, чиято стойност е в набора от стойности, които изтриваме от таблица B. Обикновено това са ключове, но когато не са, тогава не може да се използва каскадно изтриване .
За да решите това, използвате CTE
WITH Bdeletes AS (
DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)
Този пример е умишлено прост, защото целта ми не е да споря за съпоставяне на ключове и т.н., а да покажа как две или повече изтривания могат да бъдат извършени от споделен набор от данни. Това също може да бъде много по-сложно, включително команди за актуализиране и т.н.
Ето един по-сложен пример (от личната база данни на Дарт Вейдър). В този случай имаме таблица, която препраща към адресна таблица. Трябва да изтрием адреси от таблицата с адреси, ако са в неговия списък с планети, които е унищожил. Искаме да използваме тази информация, за да изтрием от таблицата с хора, но само ако са били на планета (или в неговия списък за убийства на трофеи)
with AddressesToDelete as (
select AddressId from Addresses a
join PlanetsDestroyed pd on pd.PlanetName = a.PlanetName
),
PeopleDeleted as (
delete from People
where AddressId in (select * from AddressesToDelete)
and OffPlanet = false
and TrophyKill = false
returning Id
),
PeopleMissed as (
update People
set AddressId=null, dead=(OffPlanet=false)
where AddressId in (select * from AddressesToDelete)
returning id
)
Delete from Addresses where AddressId in (select * from AddressesToDelete)
Сега неговата база данни е актуална. Няма повреди в целостта поради изтриване на адрес. Имайте предвид, че въпреки че връщаме данни от актуализацията и първото изтриване, това не означава, че трябва да ги използваме. Не съм сигурен дали можете да поставите изтриване в CTE без върнати данни (Моят SQL също може да греши при използването на връщане от актуализация - не успях да тествам това, тъй като Darth V. беше в капризно настроение.