電子書籍の厳選無料作品が豊富!

VB6及びSQLServer2000で開発を行っているのですが
1つのテーブルに対して一度に複数の行ロックを
行う事が出来ずに困っています。

通常と違う方法が必要なのか、何か注意点があるのでしょうか?
よろしくお願いします

A 回答 (4件)

単に、PKがIDだけではないとか、トランザクションをかけていないだけではないですか?



現在業務中のため、手元に環境がSQLサーバしかないので、
・クエリアナライザ
・VBScript
でやってみましたが、問題なしで普通にロックがかかりました。。。


私の行った方法が、そちらでもそのまま実現できるように、全て張っておきます。


※1.テスト環境構築⇒pubs設定にしてあります
----------------------------------------------------------------------------------------------------------------

USE pubs
GO

if EXISTS(SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[TBL_NAME]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [TBL_NAME]
GO

CREATE TABLE [TBL_NAME] (
[ID] [numeric](8, 0) NOT NULL ,
[FLD] [char] (8) COLLATE Japanese_BIN NOT NULL
CONSTRAINT [XPKTBL_NAME] PRIMARY KEY CLUSTERED
(
[ID]
) ON [PRIMARY]
)
GO

INSERT INTO TBL_NAME VALUES(1,'A')
INSERT INTO TBL_NAME VALUES(2,'B')
INSERT INTO TBL_NAME VALUES(3,'C')
INSERT INTO TBL_NAME VALUES(4,'D')
INSERT INTO TBL_NAME VALUES(5,'E')

GO
SELECT * FROM TBL_NAME
GO
----------------------------------------------------------------------------------------------------------------



※2.ロック用のVBScript
(必要に応じてGetConnection()関数を変更してください)
----------------------------------------------------------------------------------------------------------------
Option Explicit

Call Main_Lock()

'メイン:ロック
Sub Main_Lock()

Dim adoCnn
Dim adoRec
Dim strSQL

Set adoCnn = GetConnection()
adoCnn.BeginTrans


strSQL = "SELECT * FROM TBL_NAME with (rowlock,updlock) WHERE ID IN(2,3,4)"
Set adoRec = adoCnn.Execute(strSQL)

MsgBox adoRec.RecordCount & "件のデータをロック中...更新用のVBScriptを実行ください"

adoCnn.CommitTrans
'またはRollbackTrans

adoCnn.Close
Set adoCnn = Nothing

End Sub


'汎用:コネクション
Private Function GetConnection()

CONST ADO_CUR_LOCATION_SERVER = 2 'ADODB.CursorLocationEnum.adUseServer
CONST ADO_CUR_LOCATION_CILENT = 3 'ADODB.CursorLocationEnum.adUseClient

Set GetConnection =CreateObject("ADODB.Connection")
GetConnection.CursorLocation = ADO_CUR_LOCATION_CILENT
GetConnection.Open "Provider=SQLOLEDB;" & _
"Data Source=(local);" & _
"Initial Catalog=pubs;", "sa", "sa"
End Function
----------------------------------------------------------------------------------------------------------------


※3.更新用のVBScript
(必要に応じてGetConnection()関数を変更してください)
----------------------------------------------------------------------------------------------------------------
Option Explicit


Call Main_Update()


'メイン:更新
Sub Main_Update()

Dim adoCnn
Dim strSQL

Set adoCnn = GetConnection()

strSQL = "UPDATE TBL_NAME SET FLD = 'わ' WHERE ID = 1"
Call adoCnn.Execute(strSQL)
Call Msgbox("STEP 1 終了")

strSQL = "UPDATE TBL_NAME SET FLD = 'わ' WHERE ID = 4"
Call adoCnn.Execute(strSQL)
Call Msgbox("STEP 2 終了")

strSQL = "UPDATE TBL_NAME SET FLD = 'わ' WHERE ID = 5"
Call adoCnn.Execute(strSQL)
Call Msgbox("STEP 3 終了")

adoCnn.Close
Set adoCnn = Nothing

End Sub




'汎用:コネクション
Private Function GetConnection()

CONST ADO_CUR_LOCATION_SERVER = 2 'ADODB.CursorLocationEnum.adUseServer
CONST ADO_CUR_LOCATION_CILENT = 3 'ADODB.CursorLocationEnum.adUseClient

Set GetConnection =CreateObject("ADODB.Connection")
GetConnection.CursorLocation = ADO_CUR_LOCATION_CILENT
GetConnection.Open "Provider=SQLOLEDB;" & _
"Data Source=(local);" & _
"Initial Catalog=pubs;", "sa", "sa"
End Function
    • good
    • 0
この回答へのお礼

返事が遅くなってすみませんでした。
おかげさまで、無事解決する事が出来ました。
ロック時のトランザクションのタイミングが悪かったようです。
ありがとうごさいました。

お礼日時:2005/12/12 10:43

SQL自体を見ると、なぜロックされないのか不思議ですね。


SQLServerの識者にも聞いてみたんですが、Primary以外にインデクスを張っていると、
まれにそんな現象が起きてたかもしれないみたいなことを言ってました。
さらに、トランザクションの分離レベルとかの問題もあるんじゃないのかともいってます。
(要はプログラマレベルの作業でなくSE作業だから現地環境見ないとわからないとのことなのです)

※お役にたてずすいません。Oracleなどと違ってSQLServerは資料も少なくて大変ですね。
    • good
    • 0
この回答へのお礼

返事が遅くなってすみませんでした。
おかげさまで、無事解決する事が出来ました。
ロック時のトランザクションのタイミングが悪かったようです。
ありがとうごさいました。

お礼日時:2005/12/12 10:45

補足にかかれた内容で行ロックをかけるとして、どのようなSQLを組んでいますか?


また、そのSQLでロックを書けた場合にロックがかからない状態とは、どのようなことを言うのでしょうか?
(例:IDが2のみロック、3,4にかからない等)

この回答への補足

先の表にたとえると
select * from TBL_NAME with (rowlock,updlock)
where ID in (2,3,4)
といったSQLです

実際にロックが掛かるのは一行のみです(IDが2)

補足日時:2005/11/30 14:54
    • good
    • 0

>一度に複数の行ロック


WHERE句に指定している行にロックをかけたいが、かからないということですか?

まさか、PrimaryKeyは違うというおちではないですよね?

少し具体的に補足していただけますか?

この回答への補足

ロックするの対象はPrimatyKeyです

ID NAME
1 AAA
2 BBB
3 CCC
4 DDD

といった表があった場合、IDが2,3,4の行を同時に
ロックしたい場合のケースです

補足日時:2005/11/30 13:49
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す