こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

グループ単位での更新・追加・削除

ID(キー)と、分類コードを持つテーブル(A、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
INTO @TBL_A_ID

WHILE @@FETCH_STATS = 0
BEGIN

IFNOT 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

END

END

以上です。
やりたいこととしては、Aテーブルを分類コード(起動引数)単位でループさせて、
Bテーブルにも同じIDのデータがあったら、Aテーブルから削除させたいです。

しかし、Aテーブルをカーソルループさせているので、それを削除しながら回すと
おかしくなるでしょうか。
事情により、1行ずつ読み込んで削除していきたいので、ループさせたいのですが…。
ループのやり方がまずいのか、他の原因があるのか、SQLManagementStudioから
上のSPを実行しても、うまくいきませんでした。
(見よう見まねで作っているので、他にもおかしいところがあると思いますが)

修正すべき点等、ご指摘いただけないでしょうか。

投稿日時 - 2011-03-09 22:50:16

QNo.6582422

すぐに回答ほしいです

質問者が選んだベストアンサー

こんにちは。
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

投稿日時 - 2011-03-22 18:47:35

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

カーソル使わずに
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;
でもいいかも。

投稿日時 - 2011-03-10 13:07:17

ANo.1

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;

でどうでしょうか。

投稿日時 - 2011-03-10 01:24:31