【问题标题】:Deleting record from table is not actually deleting VBA Access从表中删除记录实际上并没有删除 VBA Access
【发布时间】:2017-10-25 22:29:52
【问题描述】:

我有一个名为 Scenarios 的表,它与 ESDNodes 有一对多的关系。可以有多个 ESDNode 引用一个场景。

对于每个场景必须至少有一个 ESDNode,这意味着当要删除一个场景时,必须删除其所有相关的 ESDNode。

所以当用户选择一个场景并试图删除它时,这个函数被调用:

Private Sub Form_Delete(Cancel As Integer)
  Dim scenID As Long
  Dim ESDHeadNodeID As Long
  Dim response As Long
  Dim style As Long

  scenID = Forms!Main!Scenarios!ScenarioID
  ESDHeadNodeID = DLookup("ESDNodeID", "ESDNodes", "((ESDNodes.ESDNodeType)=1) AND ((ESDNodes.ScenarioID) = " & scenID & ")")

  style = vbYesNoCancel + vbQuestion
  response = MsgBox("Are you sure you wish to delete all selected nodes and their children?", style)
  If response = vbYes Then
     DeleteESDChildren (ESDHeadNodeID)
     loadESDTreeView
  End If
End Sub

在 DeleteESDChildren 中,我处理删除所有相关的 ESDNode。我删除了与此函数中的错误无关的所有代码。 这是那个函数:

Public Function DeleteESDChildren(lngID As Long)
  Dim rst_Del As Recordset
  Set rst_Del = CurrentDb.OpenRecordset("SELECT * FROM ESDNodes WHERE ESDNodeID = " & lngID)

  rst_Del.MoveFirst

  'Delete the head node
  If Not rst_Del.EOF Then
     rst_Del.Delete 
  End If
End Function

我用最简单的情况测试了这段代码,其中一个场景只有一个 ESDNode 并且 ESDNode 没有子节点。调用 rst_Del.Delete 的行,我希望删除这个奇异的 ESDNode。但是,当 Form_Delete 尝试 End Sub 声称“无法删除或更改记录,因为表 'ESDNodes' 包含相关记录”时,我收到错误消息。所以这个单一的 ESDNode 不会被删除。

显示我的表之间关系的屏幕截图

【问题讨论】:

  • 你如何到达那条线?看起来您在 DeleteESDChildren 的前 5 行中处于循环状态。没有?
  • 有什么理由不使用 SQL delete 查询而不是 select 查询来删除相关的 ESDnodes 吗? ....然后运行另一个删除查询以删除场景记录。
  • 请张贴您的关系图的屏幕截图(功能区 > 数据库工具 > 关系),重点关注 ESDnodes
  • 有趣的是,您有很多指向 ESINodes 的链接,并且看起来是同一个表引用完整性。看起来 FTNodes 是一个子表,因此您必须先删除那里的所有相应行,然后才能从 ESINodes 中删除。但是ESINode_1也可能是个问题。
  • 另外,仅供参考,如果“1”表在左侧,“许多”表在右侧,则更容易阅读关系图,因此您会看到左侧的父母和与父母相关的孩子对。

标签: ms-access vba


【解决方案1】:

这可以使用 SQL 来实现

CurrentDb.Execute "DELETE * FROM ESDNodes WHERE ESDNodeID = " & lngID

【讨论】:

    【解决方案2】:

    看起来你陷入了循环。

    Public Function DeleteESDChildren(lngID As Long)
        Dim rst As Recordset
        'find the children of the node
        Set rst = CurrentDb.OpenRecordset("SELECT * FROM ESDNodes WHERE ParentID = " & lngID)
    
        'call deletechildren on each child in turn
        While Not rst.EOF
            DeleteESDChildren (rst!ESDNodeID) '<-- goes back to the beginning.
            rst.MoveNext
        Wend
        etc.
    

    【讨论】:

    • 该行用于删除该 ESDNode 的子节点。换句话说,ESDNodes 与其他 ESDNodes 之间存在一对多的关系。但是我正在使用最简单的测试用例测试代码,它只是一个没有子节点的 ESDNode,因此记录集将为空并且不会进入该循环。
    • 我想我可以把这段代码注释掉,以免混淆任何人
    • 啊,我知道你在那里做了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    相关资源
    最近更新 更多