2

したがって、次のテーブルがあります(無関係な列は省略されています):

CREATE TABLE [dbo].[Step]
(
   [StepId] INT NOT NULL PRIMARY KEY IDENTITY, 
   [ParentStepId] INT NULL,

   CONSTRAINT [FK_Step_ParentStep] FOREIGN KEY ([ParentStepId]) REFERENCES [Step]([StepId])
)

CREATE TABLE [dbo].[StepInput]
(
   [StepInputId] INT NOT NULL PRIMARY KEY IDENTITY, 
   [StepId] INT NOT NULL, 
   [ChildStepId] INT NULL,

   CONSTRAINT [FK_StepInput_Step] FOREIGN KEY ([StepId]) REFERENCES [Step]([StepId]), 
   CONSTRAINT [FK_StepInput_ChildStep] FOREIGN KEY ([ChildStepId]) REFERENCES [Step]([StepId]),
)

ゼロから多数の StepInputs を持つ Step があります。StepInput にはオプションの子 Step があり、Step にはオプションの親 Step (自己参照) があります。

これは期待どおりに機能します。ここで実行できるようにしたいのは、ステップを削除し、そのステップに関連付けられているすべての StepInputs と、子ステップとその入力も削除することです。

Entity Framework 5 を使用しています。EF でこれを行う便利な方法はありますか、またはストアド プロシージャを作成する必要がありますか、FK 制約にカスケード オプションを設定する必要がありますか、それともより良い解決策が他にありますか?

ON DELETE CASCADE をさまざまな方法で使用してみましたが、何も機能しませんでした。また、階層データに関してはカスケード削除に頼るべきではないことも読みましたが、提案された代替案 (CTE?) を本当に理解していませんでした。

ParentStepId 列を削除すると、作業が簡単になりますか? ステップが最上位のステップであるかどうかを判断することが唯一の実用的な方法であり、ビット フィールドを使用するのと同じくらい簡単に使用できます。間に StepInput を含まない親子関係はありません。

SQL全般、特にSQL Serverに関しては、私は明らかにかなりグリーンなので、答えを覚えておいてください;)

4

1 に答える 1

1

stepIdを指定してすべての行を削除する簡単な手順を試して作成しました

DECLARE @stepId int
SET @stepId = 1

DECLARE @Delete TABLE
(
  id int
)

;WITH IdsToDelete (id)
AS (
  SELECT ChildStepId
  FROM StepInput
  WHERE StepId = @stepId
  UNION ALL
  SELECT s.ChildStepId
  FROM StepInput s
  INNER JOIN IdsToDelete I ON I.id = s.StepId
)



INSERT INTO @Delete (id)
  SELECT id
  FROM IdsToDelete



DELETE FROM StepInput WHERE StepId = @stepId OR StepId IN (SELECT Id FROM @Delete)
DELETE FROM Step WHERE StepId IN (SELECT Id FROM @Delete) OR StepId = @stepId

アイデアは、再帰的なcteを作成し、削除するすべてのIDを保存してから宣言されたテーブルに保存することです.cteは最初のステートメントの後にデータを失います.

次に、IDがそのテーブルにあるすべてのものを削除する必要があります。また、すべての削除を失敗させているステップ テーブルの制約も削除しました。

今回はうまくいったと思います。そこで私が何をしたかを理解していただければ幸いです。

乾杯、

于 2013-08-12T22:51:00.937 に答える