有没有一种方法可以锁定Access数据库中的记录

时间:2019-03-26 15:23:21

标签: sql excel vba ms-access

我需要找到一种在多用户环境中从MS Access数据库获取唯一“验证”的方法。这是我的表格示例:

enter image description here

字段验证已经预先填写,并且将永远不会更改,mID和getDate将由用户添加/删除(使用VBA脚本)。
VBA脚本的规则是:
1.找到mID的第一行,
2.填写当前用户名和当前日期,
3.返回相应的验证字段

似乎很容易做到,这是我开发的代码:

Function access() As String

    Dim con As ADODB.Connection
    Dim Records As ADODB.Recordset
    Dim record As ADODB.record

    Set con = New ADODB.Connection
    Set Records = New ADODB.Recordset
    Set record = New record

    con.ConnectionString = sDBPath
    con.Open

    With Records
        .ActiveConnection = con
        .Source = "tblVerificationNr"
        .LockType = adLockOptimistic
        .CursorType = adOpenDynamic
        .Open

    Do Until .EOF
        If IsNull(.Fields("mID")) Then
            access = .Fields(1)
            .Fields("mID") = "asdf"
            .Fields("getDate") = Now
            .Update
            Exit Do
        End If
        .MoveNext
    Loop

    End With

End Function

代码对于1个用户来说效果很好,但是当多个用户(几乎)同时开始查询该代码时,他们将收到相同的验证码。 (如果User2比User1延迟发送请求0.1秒,那么他们将找到同一行-验证=3006。这将导致第一个User1将放置他的mID和getDate,并且将收到Verification = 3006,但是User2会延迟0.1秒将会覆盖此数据并收到相同的验证码)。

对此有什么解决方法?如何确保验证的唯一性?是否可以“锁定”用户1找到的记录,因此用户2将找不到该记录?

还尝试了使用SQL语句:

sSelectSQL = "SELECT TOP 1 tblVerificationNr.VerificationNumber, tblVerificationNr.Mid, tblVerificationNr.getDate FROM tblVerificationNr WHERE (((tblVerificationNr.[mID]) = '" & UserName() & "')) ORDER BY tblVerificationNr.getDate DESC, tblVerificationNr.ID"
sUpdateSQL = "UPDATE (SELECT TOP 1 tblVerificationNr.VerificationNumber, tblVerificationNr.Mid, tblVerificationNr.getDate FROM tblVerificationNr WHERE (((IsNull([tblVerificationNr].[mID]))<>False)) ORDER BY tblVerificationNr.VerificationNumber)  AS a SET a.mID = '" & UserName() & "', getDate = '" & Now() & "'"

这里是同样的问题。

1 个答案:

答案 0 :(得分:1)

我很惊讶用户得到的号码相同。尝试adLockPessimistic,而不是提取整个表,而只提取1条记录。

.Source = "SELECT TOP 1 * FROM tblVerificationNr WHERE mID IS NULL ORDER BY ID;"

如果愿意,可以按VerificationNumber排序,但可能要确保在表中对排序字段进行了索引。

然后不要循环,只需设置字段的值即可:

If Not .EOF Then
    .Fields("mID") = "asdf"
    .Fields("getDate") = Now
    .Update
    access = .Fields(1)
End If