【问题标题】:How to handle Referential Integrity for Inserts in Access如何处理 Access 中插入的参照完整性
【发布时间】:2011-11-15 21:52:28
【问题描述】:

我正在处理我从同事那里接手的 Access 项目。存在三个表:rulesoverviewrelationshiprelationship 表有两个字段,每个字段都是链接到其他两个表中的主键的外键。我有一个表格中rules 表的数据表视图,我可以在其中毫无问题地删除记录。但是,当我尝试在rules 表中插入一条记录时,该记录将插入到rules 表中,但没有匹配的记录插入到relationship 表中。我检查了“强制参照完整性”,以及“级联更新相关字段”和“级联删除相关记录”。我做了一个天真的假设,认为这会处理插入,但显然我错了。所以我现在想知道处理这个问题的最佳方法 - 我是否为表单的 After Insert 事件编写一些 VBA,相应地将记录插入到 relationship 表中?

【问题讨论】:

  • 如果您的 PK 是自动编号字段,则设置 CASCADE UPDATE 没有任何意义,因为无法更新自动编号字段。

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


【解决方案1】:

通常的方法是要么有一个表单将记录插入到规则中,该规则基于一个包含关系表的查询,例如一个允许用户选择相关概览的组合,或者一个表单/子表单集使用合适的主/子字段。在 NorthWind 示例数据库中,Order Detail 表是您的 Relationship 表的一个示例,它使用了令人讨厌的查表反功能,但您可能会得到一些进一步研究的想法。

选项 1 的更详细说明

表格

概览
身份证
概述

规则
身份证
规则

关系
RulesID ) 由两个 FK 组成的 PK
概览ID)

关系

数据

建议 1 查询设计

请注意,关系中的两个字段都包含在查询中。不需要显示规则中的 ID,因为它是一个自动编号字段,但为了简单起见,将其包含在此处。

如果删除了一行,则两个表中的记录都将被删除。

您不能违反参照完整性。您需要先创建所有概览,然后才能使用,或者提供不同的添加概览的方法。

如果您更新RulesIDOverviewID,一条记录将添加到关系表中,但不会添加到规则中。

如果您更新 OverviewIDRule,记录将同时添加到关系和规则中。

如果您创建一个连续的表单,您就可以以更加用户友好的方式获得以上所有内容,并且具有更多控制权。您可以使用组合框让用户选择更友好的概览描述,而不是 ID,您可以利用 NotInList 事件添加新概览。

请注意,到目前为止,这还不需要一行代码。这就是 Access 的力量。

【讨论】:

  • 感谢雷穆的回复。我正在尝试利用数据表视图,因为似乎所有操作(插入/更新/删除)都可以通过它完成。我的设置听起来与您在第一段中提到的相同,其中数据表视图中显示的记录基于组合框中所选的概览类型。那么,当子表单/数据表中发生插入时,您认为After Insert 是一个向relationship 表中插入新行的好地方吗?
  • 我已经使用After Insert 让它工作了。我会为遇到此问题的其他人提供一个 pastebin 链接,但它在工作中被阻止。
  • @Mitch 无需编写任何代码即可完成您想做的事情。请见上文。
  • 感谢您的详细编辑。几个问题:1)您已经在relationship 表主键中创建了外键 - 如果它们已经设置为“索引(重复确定)”,那是否有必要? 2) 将relationship 表中的主键标记栏,我的表的关系与您发布的相同。您说如果我更新 OverviewID 和 Rule,记录将被添加到关系和规则中,但这并不是我真正想要的 - 用户不应该这样做。我希望能够向rules 添加一条记录并将其传播到relationship
  • 3) 至于连续形式的东西,我很确定我已经有了。我有rules 表的数据表视图,它仅显示在关系表中具有匹配概述的规则,该规则与用户从概述组合框中选择的内容相同(不显示 ID )。
【解决方案2】:

如果有问题的键是自动编号 (IDENTITY) 并且一个表引用另一个表(通过外键),那么您可以创建一个 VIEW 连接两个表,插入到视图中,然后自动编号值得到自动复制到参考表。这是一个快速演示:

Sub RulesOverview()
  On Error Resume Next
  Kill Environ$("temp") & "\DropMe.mdb"
  On Error GoTo 0

  Dim cat
  Set cat = CreateObject("ADOX.Catalog")

  With cat
    .Create _
    "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=" & _
    Environ$("temp") & "\DropMe.mdb"

    With .ActiveConnection

      Dim Sql As String

      Sql = _
      "CREATE TABLE Rules ( " & _
      " ID INTEGER IDENTITY NOT NULL UNIQUE,  " & _
      " Rule VARCHAR(30) NOT NULL UNIQUE " & _
      ")"

      .Execute Sql

      Sql = _
      "CREATE TABLE Overview ( " & _
      " OverviewID INTEGER IDENTITY NOT NULL UNIQUE, " & _
      " Overview VARCHAR(30) NOT NULL UNIQUE " & _
      ")"

      .Execute Sql

      Sql = _
      "CREATE TABLE Relationship ( " & _
      " RuleID INTEGER NOT NULL " & _
      "    REFERENCES Rules (ID) " & _
      "    ON DELETE CASCADE, " & _
      " OverviewID INTEGER " & _
      "    REFERENCES Overview (OverviewID) " & _
      "    ON DELETE SET NULL, " & _
      " Name VARCHAR(20) NOT NULL, " & _
      " UNIQUE (RuleID, OverviewID) " & _
      ")"

      .Execute Sql

      Sql = _
      "CREATE VIEW RulesRelationship AS " & _
      "SELECT Rules.ID, " & _
      "       Rules.Rule, " & _
      "       Relationship.RuleID, " & _
      "       Relationship.Name " & _
      "  FROM Rules INNER JOIN Relationship " & _
      "          ON Rules.ID = Relationship.RuleID;"

      .Execute Sql

      Sql = _
      "INSERT INTO RulesRelationship (Rule, Name) " & _
      "   VALUES ('Don''t run with scissors', " & _
      "           'Initial scissors');"

      .Execute Sql

      Sql = _
      "SELECT * FROM RulesRelationship;"

      Dim rs
      Set rs = .Execute(Sql)
      MsgBox rs.GetString

    End With
    Set .ActiveConnection = Nothing
  End With
End Sub

【讨论】:

  • 这是否适用于 Remou 发布的表格结构对我来说不是很明显(因为这是我的简化描述)。
  • @Mitch:您的规范说,当您将记录插入rules 表时,您希望将匹配的行自动插入到关系table 中。这可以使用我发布的模型来实现(当然,我更改了表名)。但是,使用@Remou 的模型(引用),“您需要先创建所有概述,然后才能工作,或者提供添加概述的不同方法。”我选择回答你的问题,而不是基于@Remou 的回答;)
  • @Mitch:我更新了我的代码示例以使用来自@Remou 答案的元数据,添加了一个属性Relationship.Name 用于演示目的。
猜你喜欢
  • 2013-08-29
  • 1970-01-01
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多