【发布时间】:2019-03-26 15:23:21
【问题描述】:
我需要找到一种在多用户环境中从 MS Access 数据库中获取唯一“验证”的方法。这是我的表格示例:
字段验证已预先填写并且永远不会更改,mID 和 getDate 由用户添加/删除(使用 VBA 脚本)。
VBA 脚本的规则是:
1.找到mID的第一个空闲行,
2. 填写当前用户名和当前日期,
3.返回对应的Verification字段
似乎很容易做到,这是我开发的代码:
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 个用户,但当多个用户(几乎)同时开始查询它时,他们会收到相同的验证码。 (如果用户 2 比用户 1 晚 0.1 秒发送请求,那么他们会找到同一行 - 验证 = 3006。这将导致第一个用户 1 将输入他的 mID 和 getDate 并且将收到验证 = 3006,但用户 2 晚了 0.1 秒将覆盖此数据并接收相同的验证号)。
对此有什么解决方法?如何保证 Verification 的唯一性?是否可以“锁定”用户 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() & "'"
这里也是同样的问题。
【问题讨论】:
-
我认为你最好在 SQL 中使用 update/insert 和 where 子句来解决这个问题?类似的东西
update tblVerificationNr set mid='Nathan' (select min(id) where mid is null and getdate is null)新 ID 将是(select min(id) where mid is null and getdate is null) -
@HansUp 版本应该可以在条件参数中没有
[ ]的情况下工作。在 VBA 中,将这些引号更改为撇号。即使使用 SQL,用户获得相同记录的机会仍然非常非常小。我使用这种方法,从来没有遇到过问题。但是,代码不处理没有“空”记录的可能性。 -
想了很多,但
[ ]并不是真正需要的,因为字段名称没有空格或特殊字符,但它们不会造成伤害。 -
已经预填验证的任何理由?如果您将
Insertqueries 与唯一索引一起使用,则更容易防止用户发生冲突。因此,如果可能的话,每次都创建一个带有插入的新行。如果用户冲突,只有第一个可以插入数据,后面的会收到错误,可以尝试下一个验证号。如果必须预先填写验证,请使用第二个表并将验证、用户名和日期插入该表。 -
是的,这是个好主意,对新记录有帮助,但无论如何,当用户删除某些值时,我仍然需要填写空记录(请参阅我的屏幕截图中的 ID=6)