无法通过CurrentDb.Execute更新表

时间:2013-08-20 09:44:33

标签: ms-access ms-access-2007 access-vba

好的,在有人告诉我这是another question的副本之前,我认为这不是一回事。我在MS Access 2007中的VBA中运行CurrentDb.Execute,之后我将选项dbFailOnError放在我收到此错误消息之后:

  

错误3218无法更新;目前已锁定

在此之前,我正在尝试更新的表上没有做任何事情。这是表单模块中的当前代码:

Option Compare Database

Private Sub cmdvalidate_Click()
    Dim user As String
    Dim rs As Recordset
    Dim strsql As String
    Dim pass As String
    Dim f1 As Form_frmMenu

    strsql = "SELECT * FROM account WHERE username = '" & Me.txtusername & "'"

    'Execute SQL and store in recordset (cannot be stored in a string or integer)
    Set rs = CurrentDb.OpenRecordset(strsql)

    'Go through recordset and extract first value
    If rs.RecordCount > 0 Then

        rs.MoveFirst
        rs.Edit
        pass = rs!Password

        ' I know it's not the best way to validate password here (since it is
        ' case insensitive, but it's only for internal use with 3 people in
        ' the same department. This will considered if there are more people
        ' who get involved, but for the time being, this is not important.
        If pass = Me.txtpassword Then
            user = rs!UserName

' MS Access debugger says the error is here
CurrentDb.Execute "UPDATE [Account] SET [Account].[Active] = 'Y' WHERE [Account].[Username] = '" & user & "'", dbFailOnError

            MsgBox "Login Successful!"
            'DoCmd.OpenForm "frmMenu", , , , , acDialog
        Else
            MsgBox "Incorrect Username Or Password. Please try again."
        End If
    Else
        MsgBox "Something has gone wrong. Please contact your administrator."
    End If       
End Sub

我在一天结束时的目标是能够获得登录的用户名。我首先尝试使用全局变量,但似乎不可能使用不同的表单模块。因此,我创建了Active字段,以便通过SELECT语句在其他表单模块中获取用户名。

我做了一些检查:

  • 除了我之外,任何人都没有打开该文件,我完全肯定它。
  • 查询最初如下所示,但我添加了方括号,以防有保留字:
"UPDATE Account SET Active = 'Y' WHERE Username = '" & user & "'"
  • 同一文件中的其他表单模块没有此UPDATE问题,除Option Compare Database之外没有其他选项(其他内容为Private Sub)。
  • 我发现我可以使用Environ("Username")来获取其他模块中的Windows登录用户名。这将解决问题,但我仍然想知道为什么这个查询无法执行更新。

问题:

  1. 如果桌子被锁定,有没有办法解锁呢?
  2. 为什么此查询首先出错?什么锁定了它?
  3. 我不太了解,如果有关于vb的话,我甚至不确定我是如何进行这个项目的......

2 个答案:

答案 0 :(得分:1)

1。)如果桌子被锁定,有没有办法解锁呢?

我不太确定整个桌子都被锁定了。也许只有当前记录集行被锁定。见#2。

2。)为什么这个查询首先出错?是什么锁定了它?

代码rs.Edit。稍后,当直接尝试UPDATE表时,目标行是当前在记录集中锁定的行。但是,那里有更多的代码,这使得很难确定哪些语句会导致错误。

这个简化的代码示例应该澄清发生了什么。

strSql = "SELECT * FROM account WHERE username = 'hans'"
Set rs = CurrentDb.OpenRecordset(strSql)
rs.MoveFirst
rs.Edit
CurrentDb.Execute "UPDATE Account SET Active = 'Y' WHERE Username = 'hans'", dbFailOnError

如上所述,该代码在我的系统上触发错误3218,“无法更新;当前已锁定”

此更改会禁用Edit语句,并允许UPDATE成功执行。

'rs.Edit

您发现避免错误的一种方法是在执行rs.Close之前添加UPDATE。这是有效的,因为关闭记录集释放了编辑锁;如果您实际更改了该行中的值,则需要rs.Update才能在rs.Close之前保存它们。

但是,在原始版本中,您只是从记录集中读取值,而不是更改任何值。因此不需要rs.Edit

答案 1 :(得分:0)

嗯,我想我刚刚发现导致错误的原因。

显然,当RecordSet使用表格(此处为行Set rs = CurrentDb.OpenRecordset(strsql))时,表格只能通过RecordSet访问,而不能再通过CurrentDb.Execute访问(至少要更新)。< / p>

我根据具体情况找到了两种解决方法:

  1. 用某物替换CurrentDb.Execute来更新RecordSet本身(可能更容易):

    rs!Active = "Y"     ' Change the value of Active
    rs.Update           ' Update the changes to the RecordSet and thus, table
    rs.Close            ' Close recordset
    Set rs = Nothing    ' Unset recordset
    
  2. 首先关闭RecordSet,然后使用CurrentDb.Execute

    rs.Close
    Set rs = Nothing
    CurrentDb.Execute "UPDATE Account SET Active = 'Y' WHERE Username = '" & user & "'", dbFailOnError