カーソルが嫌われていることは承知しており、できるだけ使用しないようにしていますが、使用する正当な理由がある場合もあります。私は 1 つ持っており、1 組のカーソルを使用しようとしています。1 つはプライマリ テーブル用で、もう 1 つはセカンダリ テーブル用です。プライマリ テーブル カーソルは、外側のループでプライマリ テーブルを反復処理します。セカンダリ テーブル カーソルは、内側のループでセカンダリ テーブルを反復処理します。問題は、プライマリ テーブル カーソルが処理を進めてプライマリ キー列の値 [Fname] をローカル変数 @Fname に保存しているように見えますが、セカンダリ テーブルの対応する外部キー列の行を取得しないことです。セカンダリ テーブルの場合、外部キー列の値がプライマリ テーブルの最初の行のプライマリ キー列の値と一致する行を常に返します。
以下は、実際のストアド プロシージャで実行したいことの非常に単純化された例です。Names はプライマリ テーブルです。
SET NOCOUNT ON
DECLARE
@Fname varchar(50) -- to hold the fname column value from outer cursor loop
,@FK_Fname varchar(50) -- to hold the fname column value from inner cursor loop
,@score int
;
--prepare primary table to be iterated in the outer loop
DECLARE @Names AS Table (Fname varchar(50))
INSERT @Names
SELECT 'Jim' UNION
SELECT 'Bob' UNION
SELECT 'Sam' UNION
SELECT 'Jo'
--prepare secondary/detail table to be iterated in the inner loop
DECLARE @Scores AS Table (Fname varchar(50), Score int)
INSERT @Scores
SELECT 'Jo',1 UNION
SELECT 'Jo',5 UNION
SELECT 'Jim',4 UNION
SELECT 'Bob',10 UNION
SELECT 'Bob',15
--cursor to iterate on the primary table in the outer loop
DECLARE curNames CURSOR
FOR SELECT Fname FROM @Names
OPEN curNames
FETCH NEXT FROM curNames INTO @Fname
--cursor to iterate on the secondary table in the inner loop
DECLARE curScores CURSOR
FOR
SELECT FName,Score
FROM @Scores
WHERE Fname = @Fname
--*** NOTE: Using the primary table's column value @Fname from the outer loop
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Outer loop @Fname = ' + @Fname
OPEN curScores
FETCH NEXT FROM curScores INTO @FK_Fname, @Score
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ' FK_Fname=' + @FK_Fname + '. Score=' + STR(@Score)
FETCH NEXT FROM curScores INTO @FK_Fname, @Score
END
CLOSE curScores
FETCH NEXT FROM curNames INTO @Fname
END
DEALLOCATE curScores
CLOSE curNames
DEALLOCATE curNames
ここに私が結果のために得るものがあります。外側のループでは最新の Fname が表示されることに注意してください。ただし、その Fname を @Fname として使用して、後続の反復でセカンダリ テーブルから関連する行を取得すると、最初のループに一致する行が取得されます。プライマリ テーブルの行 (Bob)。
Outer loop @Fname = Bob
FK_Fname=Bob. Score=10
FK_Fname=Bob. Score=15
Outer loop @Fname = Jim
FK_Fname=Bob. Score=10
FK_Fname=Bob. Score=15
Outer loop @Fname = Jo
FK_Fname=Bob. Score=10
FK_Fname=Bob. Score=15
Outer loop @Fname = Sam
FK_Fname=Bob. Score=10
FK_Fname=Bob. Score=15
私が間違っていることを教えてください。前もって感謝します!