- PR -

パラメーター(バインド変数)を使用した場合のSQLServerロックの動作について

投稿者投稿内容
たけし
常連さん
会議室デビュー日: 2006/06/15
投稿数: 28
お住まい・勤務地: 銀河系
投稿日時: 2009-02-10 14:00
VS2005(VB) SQL Server を使用しています。
SQLの実行でロックヒントを使用してロックをかけようとしるのですが

cmd.CommandText = "SELECT * FROM TABLE1(XLOCK,ROWLOCK) WHERE FILED1 = @FIELD1 "
dr = cmd.ExecuteReader()

とすると正常にロックが働きます。

しかし、
cmd.CommandText = "SELECT * FROM TABLE1(XLOCK,ROWLOCK) WHERE FILED1 = @FIELD1 "
cmd.Parameters.Add(New SqlParameter("@FIELD1", "001"))
dr = cmd.ExecuteReader()
とパラメーターを使用するとなぜかロックがかかりません。

これってバグなのでしょうか?
ご存じの方おりましたらよろしくお願いします。

King
ぬし
会議室デビュー日: 2008/06/20
投稿数: 284
投稿日時: 2009-02-10 14:17
> cmd.CommandText = "SELECT * FROM TABLE1(XLOCK,ROWLOCK) WHERE FILED1 = @FIELD1 "
> dr = cmd.ExecuteReader()
> とすると正常にロックが働きます。

cmd.CommandText = "SELECT * FROM TABLE1(XLOCK,ROWLOCK) WHERE FILED1 = '001' "
ですか?

Parameters を使用している方ではロックをかけたいレコードは実際取得出来ているのでしょうか。
たけし
常連さん
会議室デビュー日: 2006/06/15
投稿数: 28
お住まい・勤務地: 銀河系
投稿日時: 2009-02-10 15:49
King 様

回答ありがとうございます。

> cmd.CommandText = "SELECT * FROM TABLE1(XLOCK,ROWLOCK) WHERE FILED1 = '001' "
> ですか?
そうです。訂正ありがとうございます。

レコードは実際に取得できています。
まったくもって不可解な結果となっています。

rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2009-02-10 16:39
カラム名って、正しくは FIELD1 じゃないかな…といったツッコミはおいといて、

・DB は SQL Server 2000 であってますか?
・ロックヒントが働いていることはどのようにして確認しましたか?

SQL Server でパラメータクエリを使うと、sp_executesql ストアドプロシージャ経由で実行されたと思うので、もしかしたらその辺が関係するのかも?
たけし
常連さん
会議室デビュー日: 2006/06/15
投稿数: 28
お住まい・勤務地: 銀河系
投稿日時: 2009-02-10 16:53
rain 様

回答ありがとうございます。

> カラム名って、正しくは FIELD1 じゃないかな…といったツッコミはおいといて、
そうですね。お恥ずかしいかぎりです(^^;

>・DB は SQL Server 2000 であってますか?
>・ロックヒントが働いていることはどのようにして確認しましたか?
DBは SQL Server 2005 です。
ロックヒントが働いているかどうかは、DB接続してSELECTを保持している
簡単なプログラムを作成しまして、
2つ同時に起動して確認いたしました。

> SQL Server でパラメータクエリを使うと、sp_executesql ストアドプロシージャ経由で実行されたと思うので、もしかしたらその辺が関係するのかも?
そうなんですか。ちょっと調べてみようと思います。

パラメーターを使わなくてもいいので問題はないのですが、
なぜダメなのか分からないと気持ち悪いのです。

貴重な情報ありがとうございます。


rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2009-02-10 17:07
引用:

たけしさんの書き込み (2009-02-10 16:53) より:

>・DB は SQL Server 2000 であってますか?
>・ロックヒントが働いていることはどのようにして確認しましたか?
DBは SQL Server 2005 です。



あれ、手元にあった SQL Server 2005(Express Edition) だと、
コード:
SELECT * FROM TABLE1 WITH (XLOCK,ROWLOCK) WHERE FIELD1 = '001' 


としないとクエリエラーになったんだけど、なんでだろう。
# Management Studio Express からクエリを直接実行して確認
たけし
常連さん
会議室デビュー日: 2006/06/15
投稿数: 28
お住まい・勤務地: 銀河系
投稿日時: 2009-02-10 17:33
rain さん

> SELECT * FROM TABLE1 WITH (XLOCK,ROWLOCK) WHERE FIELD1 = '001'
毎度毎度間違えてお恥ずかしいです。
そうですね。WITHが抜けていました。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2009-02-10 18:03
自己フォロー。

Management Studio Express から以下の2つのクエリを実行したところ、どちらも行ロックが取得できました。確認は利用状況モニタで行いました。
※TABLE1.FIELD1 を主キーとしました。

コード:
SELECT * FROM TABLE1 WITH (XLOCK,ROWLOCK) WHERE FIELD1 = '001';
exec sp_executesql N'SELECT * FROM TABLE1 WITH (XLOCK,ROWLOCK) WHERE FIELD1 = @FIELD1',N'@FIELD1 varchar(50)','001';



なので、↓は関係ないと思います。
引用:

rainさんの書き込み (2009-02-10 16:39) より:

SQL Server でパラメータクエリを使うと、sp_executesql ストアドプロシージャ経由で実行されたと思うので、もしかしたらその辺が関係するのかも?


スキルアップ/キャリアアップ(JOB@IT)