Att ordna ordentliga överlappande borttagningar är klokt och är vanligtvis den rätta lösningen på detta. För vissa specialfall finns det en annan lösning på detta som kan vara relevant.
Om du behöver utföra flera raderingar baserat på en gemensam uppsättning data kan du använda Vanliga tabelluttryck (CTE) .
Det är svårt att komma på ett enkelt exempel eftersom det huvudsakliga användningsfallet för detta kan täckas av kaskadraderingar.
För exemplet kommer vi att ta bort alla objekt i tabell A vars värde finns i den uppsättning värden vi tar bort från tabell B. Vanligtvis skulle dessa vara nycklar, men där de inte är det, kan överlappande radering inte användas .
För att lösa detta använder du CTEs
WITH Bdeletes AS (
DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)
Det här exemplet är medvetet enkelt eftersom min poäng inte är att argumentera om nyckelmappning etc, utan att visa hur två eller flera raderingar kan utföras från en delad datauppsättning. Detta kan också vara mycket mer komplext, inklusive uppdateringskommandon etc.
Här är ett mer komplext exempel (från Darth Vaders personliga databas). I det här fallet har vi en tabell som refererar till en adresstabell. Vi måste ta bort adresser från adresstabellen om de finns i hans lista över planeter han har förstört. Vi vill använda denna information för att radera från folktabellen, men bara om de var på planeten (eller på hans trophy-kill-lista)
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)
Nu är hans databas uppdaterad. Inga integritetsfel på grund av radering av adress. Observera att medan vi returnerar data från uppdateringen och den första raderingen, betyder det inte att vi måste använda den. Jag är osäker på om du kan lägga en radering i en CTE utan returnerad data (Min SQL kan också ha fel på användningen av att returnera från en uppdatering - jag har inte kunnat testköra detta eftersom Darth V. var i en knasig stämning.