excel 为什么.AddNew更新数据库而不执行.Update?

gv8xihay  于 2023-04-22  发布在  其他
关注(0)|答案(1)|浏览(181)

我在Excel中编写了一个函数来将记录上传到Access数据库。我在执行recordset.AddNew之后和rs.Update之前模拟了一个错误。我希望数据库不会保存记录,除非.Update执行,但是记录被保存。我的理解是,记录不应该提交到数据库,直到rs.Update执行。这里发生了什么?
下面是我的模块中的一些VBA代码,可以帮助重新创建错误(您还需要设置一个名为“EAS”的Access DB,其中包含一个名为“Statements”的表和一个名为“GroupID”的字段:

模块变量
'Connection
Const PWORD As String = "password"
Dim sSQL As String 'SQL string
Dim cnn As New ADODB.Connection 'ADODB Connection object
Dim rs As New ADODB.Recordset 'ADODB Recordset object

'Paths
Const EAS_DB As String = "J:\yourpath\EAS.accdb"
打开数据库连接
Private Sub openConnect()
'opens the DB connection, let errors occur

Dim cnnString As String
    cnnString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                "Data Source=" & EAS_DB & ";" & _
                "Jet OLEDB:Database Password='" & PWORD & "';"
    cnn.Open cnnString
End Sub
关闭数据库连接
Private Sub closeConnect()
'closes recordset and connection cleanly, handle errors

Dim rsFail As Boolean
    rsFail = True

On Error GoTo eh:
    If Not rs Is Nothing Then
        If rs.State = adStateOpen Then
            rs.Close
            Set rs = Nothing
        End If
    End If      

closeCnn:
    rsFail = False
    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then
            cnn.Close
            Set cnn = Nothing
        End If
    End If
Exit Sub
   
eh:
    If rsFail Then
        GoTo closeCnn:
    Else
        MsgBox Err.Source & vbNewLine & vbNewLine & Err.Description, , "Error in closeConnect"
    End If
End Sub
记录到数据库的函数
Private Function createPendingRecord(ByVal idarray As Variant, ByVal amount As Double) As Boolean
'Attempts to create a new pending record in the database, returns boolean result

Dim data As Variant
Dim flds As Variant  

'Get data and field arrays for upload
data(0) = "12345"
flds(0) = "GroupID"

On Error GoTo eh:
  
    openConnect
    rs.Open "Statements", cnn, adOpenDynamic, adLockOptimistic
    rs.AddNew flds, data
    Error 0
    rs.Update
    createPendingRecord = True

cleanExit:
    closeConnect
    Exit Function

eh:
    MsgBox Err.Source & vbNewLine & vbNewLine & Err.Description, , "Error in createPendingRecord"
    Resume cleanExit
   
End Function

正如你所看到的,我在rs.AddNewrs.Update之间插入了一行Error 0。这会触发错误处理程序,代码使用closeConnect退出,而不执行rs.Update。但是,之后该记录会出现在数据库中。
我的理解是不应该。困惑。请有人能解释一下这是怎么回事吗?

5f0d552i

5f0d552i1#

你的理解是错误的。这是有意的行为。
查看docs
AddNew方法的行为取决于对象的更新模式以及是否传递Fieldlist和Values参数。
在立即更新模式下(在这种情况下,一旦调用Update方法,提供程序就将更改写入基础数据源),调用不带参数的AddNew方法会将EditMode属性设置为adEditAdd(EditModeEnum值)。提供程序将在本地缓存任何字段值更改。调用Update方法将新记录发送到数据库,并将EditMode属性重置为adEditNone(EditModeEnum值)。如果传递Fieldlist和Values参数,ADO将立即将新记录发送到数据库(不需要Update调用);EditMode属性值不会更改(adEditNone)。
由于您传递的是字段和值列表,并且没有使用批处理模式,因此新记录会立即写入,后续的.Update是不必要的。
如果你想取消操作,最直接的方法是使用事务(参见this),这将允许你更好地控制何时将更改写入数据库。
或者,您可以逐个分配字段和值,而不使用.AddNew中的字段和值列表,这将适用于此特定操作。

相关问题