在Access 2003数据库中,我有一个“Inscriptions”(订阅)数据库,其中包含2个字段idPersonnel(employee)和idSession的主键。 我创建了一个表单,以便用户可以选择一个会话(在列表框中),然后选择一个或多个员工(另一个列表框)并使用一个按钮将它们挂到该会话中,在VBA端,首先检查是否有足够的会议室(由“会话”表上的“MaxParticipants”字段定义,链接到idSession上的“铭文”表),然后在“铭文”表中插入数据
这在单用户环境中工作正常,但如果2个人想同时在同一会话中加入某些员工,则会失败,因为我在检查和插入之间有确认消息。因此,2个用户可以选择员工,获取确认消息(此时两者都被告知有足够的空间),导致有更多的人加入会话。 幸运的是,如果两个用户都试图将相同的员工插入到该表中,则会出现重复错误,但如果员工不同,则会进行插入。
在另一个数据库引擎上,比如SQL服务器,我会使用一个存储过程来锁定表,执行检查和插入然后解锁表。
但在MS Access中似乎不可能。 MS Access有哪些可能阻止会话超过最大参与者数量?任何帮助表示赞赏。
答案 0 :(得分:2)
实现目标的一种方法是在事务中执行INSERT,计算该会话的参与者,并在新的总数超过限制时回滚事务:
Option Compare Database
Option Explicit
Sub AddParticipant()
Dim cdb As DAO.Database, cws As DAO.Workspace, _
qdf As DAO.QueryDef, rst As DAO.Recordset
' test data
Const idPersonnelToAdd = 4
Const idSessionToAdd = 2
Set cdb = CurrentDb
Set cws = DBEngine.Workspaces(0)
cws.BeginTrans
Set qdf = cdb.CreateQueryDef("", _
"PARAMETERS prmIdPersonnel Long, prmIdSession Long; " & _
"INSERT INTO Inscriptions (idPersonnel, idSession) " & _
"VALUES (prmIdPersonnel, prmIdSession)")
qdf!prmIdPersonnel = idPersonnelToAdd
qdf!prmIdSession = idSessionToAdd
qdf.Execute dbFailOnError
Set qdf = Nothing
Set qdf = cdb.CreateQueryDef("", _
"PARAMETERS prmIdSession Long; " & _
"SELECT " & _
"Count(*) AS NumParticipants, " & _
"First(MaxParticipants) AS Limit " & _
"FROM Inscriptions INNER JOIN Sessions " & _
"ON Inscriptions.idSession = Sessions.idSession " & _
"WHERE Sessions.idSession = prmIdSession")
qdf!prmIdSession = idSessionToAdd
Set rst = qdf.OpenRecordset(dbOpenSnapshot)
If rst!NumParticipants <= rst!Limit Then
cws.CommitTrans
Debug.Print "INSERT committed"
Else
cws.Rollback
Debug.Print "INSERT rolled back"
End If
rst.Close
Set rst = Nothing
Set qdf = Nothing
Set cws = Nothing
Set cdb = Nothing
End Sub