1

カーソルを使用してテーブル内の行を並べ替えるスクリプトがあります。たとえば、テーブルは SSN、Kid_SSN、Kid_DOB、Seq# のようになり、1 人以上の子供を持つすべての人をリストします。Seq# を更新して、生年月日に基づいて各子供に 1、2、3 のラベルを付けたいと考えています。SQL Server 2008で更新にカーソルを使用して正常に実行しました。現在の問題は、この同じスクリプトがSQL Server 2012で期待どおりに実行されないことです。問題は、SQL 2012カーソルフェッチNEXTで一度に1行以上です. 質問は、カーソルのフェッチ サイズをどこで設定できるかということです。色々と調べてみましたが、良い答えが見つかりませんでした。ここに誰か光を当てることができますか?ありがとう。

スクリプトは次のようになります。

DECLARE @SocialSecurity varchar(9), @PersonID int, @Dep_SSN varchar(9)
DECLARE @LastName varchar(20), @FirstName varchar(20), @BirthDate datetime, 
    @Number int

DECLARE @ssn varchar(9) = '000000000'
DECLARE @Mem int = 1
DECLARE cur cursor
FOR SELECT * FROM kids
FOR UPDATE OF Number;

OPEN cur;

FETCH NEXT FROM cur INTO @SocialSecurity, @PersonID, @Dep_SSN, @LastName, @FirstName, 
    @BirthDate, @Number;

WHILE @@FETCH_STATUS = 0
BEGIN

IF @SocialSecurity = @ssn
BEGIN

UPDATE kids
SET Number = @Mem+1
WHERE CURRENT OF cur
SET @Mem = @Mem+1
END;
ELSE
BEGIN
SET @ssn = @SocialSecurity
SET @Mem = 1
END;
FETCH NEXT FROM cur INTO @SocialSecurity, @PersonID, @Dep_SSN, @LastName, @FirstName, 
    @BirthDate, @Number;
END;
CLOSE cur;
DEALLOCATE cur;

この問題の詳細。kids は「SELECT .. INTO」によって生成された一時テーブルで、単純化されたセットは次のようになります

SSN       Kid_SSN        DOB        Seq#
123123123 987987987      1/1/2000   1
123123123 987987988      1/1/2003   1
123123125 890890890      2/3/2002   1

したがって、すべての seq# は 1 に開始されます。上記のスクリプトを実行した後、テーブル キッズは次のようになると予想されます。

SSN       Kid_SSN        DOB        Seq#
123123123 987987987      1/1/2000   1
123123123 987987988      1/1/2003   2
123123125 890890890      2/3/2002   1

スクリプトはサーバー 2008 R2 でこれを達成するために完全に実行されましたが、サーバー 2012 では実行されませんでした。そのため、カーソルは一度に 88 行をフェッチすると思います。しかし、サーバー2008では、予想どおり一度に1行ずつフェッチされるようです。これが私が抱えている問題を説明することを願っています。効率的ではありませんが、サーバー2012で機能させるために、カーソルを一度に1行ずつ強制的に取得したいと考えています。または、カーソルを使用せずにシーケンスを行う方法は? ありがとう。

4

2 に答える 2

2

スクリプト全体をランクオーバー関数に置き換えてもうまくいきますか?

何かのようなもの

select *, rank() over (partition by SSN, Kid_DOB order by Kid_SSN) as SeqNum
from kids

これはうまくいくはずだと思いますが、うまくいかない場合は、パーティションを微調整して並べ替えることができます。

于 2012-10-23T21:34:36.560 に答える
1

スクリプトでは、カーソルがkids同じ SSN でレコードをグループ化する必要があります。しかし、これを強制する ORDER BY はありません。@Memしたがって、レコードはランダムな順序で返され、カウンターが台無しになります。

SQL 2012 対 2008 の問題ではありません。単に SQL 2008 で運が良かっただけで、レコードが既に希望どおりに並べられていたか、SQL 2008 が順序付けされていない結果を選択するための動作が異なるか、または pk を定義し、インデックスが異なります。

于 2012-10-24T01:43:38.280 に答える