適切なカスケード削除を手配することは賢明であり、通常はこれに対する正しい解決策です。特定の特殊なケースでは、これに関連する可能性のある別の解決策があります。
共通のデータセットに基づいて複数の削除を実行する必要がある場合は、を使用できます。共通テーブル式(CTE) 。
この主な使用例はカスケード削除でカバーできるため、簡単な例を思い付くのは困難です。
この例では、テーブルBから削除する値のセットに値が含まれているテーブルAのすべてのアイテムを削除します。通常、これらはキーになりますが、そうでない場合は、カスケード削除を使用できません。 。
これを解決するには、CTEを使用します
WITH Bdeletes AS (
DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)
この例は、キーマッピングなどについて議論することではなく、共有データセットから2つ以上の削除を実行する方法を示すことであるため、意図的に単純です。これも、更新コマンドなどを含め、はるかに複雑になる可能性があります。
これはより複雑な例です(Darth Vaderの個人データベースから)。この場合、アドレステーブルを参照するテーブルがあります。彼が破壊した惑星のリストにアドレスがある場合は、アドレステーブルからアドレスを削除する必要があります。この情報を使用してpeopleテーブルから削除したいのですが、それは彼らが惑星上にいる場合(または彼のトロフィーキルリストにある場合のみ)です
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は、更新からの戻りの使用についても間違っている可能性があります-ダースVが気難しい気分。