- ベストアンサー
Aテーブルを分類コード単位でループさせてBテーブルからデータを削除するストアドの修正点について
- Aテーブルを分類コード単位でループさせてBテーブルに同じIDのデータが存在する場合、Aテーブルからそのデータを削除するストアドについて修正すべき点について教えてください。
- 修正したいストアドでは、カーソルループを使用してAテーブルを走査し、Bテーブルに同じIDのデータがあるかどうかを判定します。もし同じIDのデータがあればAテーブルからそのIDのデータを削除するという処理を行いたいのですが、上記のストアドには問題があります。
- ストアドの問題点は、カーソルループ内で一度データを削除すると、ループ処理が継続できなくなるということです。つまり、Aテーブルからデータを削除する際に、同時にループ処理も終了してしまいます。そのため、現在のストアドではうまく動作していないのです。修正する必要があります。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 Bテーブルでループしては?と思いましたがとりあえず書いてみました。 動作確認はしていませんので間違えてる部分があるかもしれません。 気になったところを追記削除しています。 どんなエラーが出るか書いていただけるとより答えやすいです。 以下にコードを記述します。 ALTER PROCEDURE XXX @BunruiCD CHAR(10) AS BEGIN DECLARE @TBL_A_ID CHAR(5) DECLARE TBL_A_DATA CURSOR FOR SELECT A.ID FROM TBL_A WHERE BUNRUI_CD = @BunruiCD --begin(必要ないと思います) OPEN TBL_A_DATA FETCH NEXT FROM TBL_A_DATA --ここで 1つめのデータを入れます INTO @TBL_A_ID --ループ開始 WHILE @@FETCH_STATS = 0 BEGIN IF NOT EXISTS(SELECT * FROM TBL_B WHERE ID = @TBL_A_ID) BEGIN --Bテーブルにデータが存在した場合は削除する DELETE FROM TBL_A WHERE TBL_A_ID = @TBL_A_ID END ELSE BEGIN --特に処理なし(UPDATE等する予定) END FETCH NEXT FROM TBL_A_DATA --次のデータを入れます INTO @TBL_A_ID END CLOSE TBL_A_DATA--終わったらカーソルを閉じます DEALLOCATE TBL_A_DATA--終わったらカーソルを削除します END
その他の回答 (2)
- nora1962
- ベストアンサー率60% (431/717)
カーソル使わずに ALTER PROCEDURE Proc_test @BunruiCD CHAR(5) AS BEGIN DELETE FROM TBL_A WHERE BUNRUI_CD = @BunruiCD AND EXISTS ( SELECT 1 FROM TBL_B WHERE TBL_A.ID=TBL_B.ID ) END; でもいいかも。
- nora1962
- ベストアンサー率60% (431/717)
ALTER PROCEDURE Proc_test @BunruiCD CHAR(10) AS BEGIN DECLARE @TBL_A_ID CHAR(5); DECLARE TBL_A_DATA CURSOR FOR SELECT A.ID FROM TBL_A A WHERE BUNRUI_CD = @BunruiCD; BEGIN SET NOCOUNT ON; OPEN TBL_A_DATA; FETCH NEXT FROM TBL_A_DATA INTO @TBL_A_ID; WHILE @@FETCH_STATUS = 0 BEGIN --Bテーブルにデータが存在した場合は削除する IF EXISTS ( SELECT 1 FROM TBL_B WHERE TBL_B.ID=@TBL_A_ID ) DELETE FROM TBL_A WHERE CURRENT OF TBL_A_DATA; FETCH NEXT FROM TBL_A_DATA INTO @TBL_A_ID; END; CLOSE TBL_A_DATA; END; END; でどうでしょうか。