2012-01-22 8 views
10

私はSQL Server 2008を使用しています。SQL Server - マルチスレッドアプリケーションで@@ ROWCOUNTを安全に使用していますか?

私は1秒で多くの挿入/更新を受け入れるテーブルAを持っています。挿入後、更新私は影響を受ける行の数を取得したい。

INSERT INTO A (ID) VALUES (1) 
IF @@ROWCOUNT = 0 
    PRINT 'NO ROWS AFFECTED' 

クエリが実行されている間、同じクエリがアプリケーションによって再度呼び出されることがあります。では、現在の実行がINSERTの後、IFブロックの前にの場合は、その時点でとなります。

あなたは@@ROWCOUNTがその理由で間違った結果をもたらすかもしれないと思いますか?

また、その文脈では常に安全ですか?

答えて

20

はい - 安全です。なぜならIF文の後のカウント@@ROWCOUNTリセット

それは常に、あなたが影響を受けた行数を知りたい場合は、 は変数最初に保存

しかし

現在のクエリでは、前の操作を指し、

INSERT INTO A (ID) VALUES (1) 
DECLARE @rc INT = @@ROWCOUNT 
IF @rc = 0 
    PRINT 'NO ROWS AFFECTED' 
ELSE 
    SELECT @rc AS RowsAffected 
6

@@ ROWCOUNTはスコープと接続の両方に安全です。

実際、その接続とスコープの最後の文の行数だけを読み取ります。 here on MSDN(カーソル、DML、EXECUTEなど)

次の文で使用するには、ローカル変数に格納する必要があります。

1

あなたは必見がそうでなければIF文の後に、その値がゼロにリセットされます、ローカル変数に@@ROWCOUNT価値を維持:

それ以外
SET @rowCount = @@ROWCOUNT 

IF @rowCount = 0 
    PRINT 'NO ROWS AFFECTED' 

は、はい、それは安全です。

+0

MS SQL 2008 R2 DBに対してこれをテストしましたが、 '@@ ROWCOUNT'に対する' IF'チェックは問題なく動作しました。何かをする前にいつも '@@ ROWCOUNT'をローカルに保存することは良い習慣であると理解できます。しかし、どうしてあなたは**最初にそれをローカル変数に保存しなければならないと言ったのですか?これは良い習慣であるか、 '@@ ROWCOUNT'の値を直接チェックすることは本当に信頼できないのでしょうか? – Sam

+0

アクセスする前に値を保存する必要があります。 –

+1

私はこれが必要であることを示す参考文献を見つけるために少し調べましたが、私は見つけられませんでした。これを行う必要があることを実証するために提供できる参考資料または情報源はありますか? – Sam

0

短い答え:はい。

しかし、その答えが疑いもなく自然である理由をより深く理解するためには、問題を視点で見る価値があります。

SQL Serverは、クライアントアプリケーションがマルチスレッドであるかどうかにかかわらず、その性質上、同時アクセスを正しく処理できるように準備されています。この属性のSQL Serverがであれば、マルチユーザーのシナリオでは役に立たない場合を除きます。サーバの観点から見ると、マルチスレッドアプリケーション、または現在複数のユーザが同時にサーバを使用している2つのアプリケーションによって引き起こされる同時アクセスが問題ではありません。

この点に関して、@@ rowcountは氷山の先頭に過ぎません。並行アクセスが画像内にある場合、正しく処理されなければならない機能はますます深くなります。

この領域の最も実用的な部分は、トランザクション管理とトランザクション分離です。