Ms access 如何处理Access中插入的引用完整性

Ms access 如何处理Access中插入的引用完整性,ms-access,vba,ms-access-2007,Ms Access,Vba,Ms Access 2007,我正在做一个接入项目,我从一个同事那里接手了这个项目。存在三个表:规则、概述和关系。关系表有两个字段,每个字段都是一个外键,链接到其他两个表中的主键。我有一个表单中规则表的数据表视图,在那里我可以毫无问题地删除记录。但是,当我尝试将记录插入到规则表中时,该记录将插入到规则表中,但在关系表中没有插入匹配的记录。我检查了“强制引用完整性”以及“级联更新相关字段”和“级联删除相关记录”。我天真地认为这可以处理插入,但显然我错了。因此,我现在想知道处理这个问题的最佳方法-我是否为表单的插入后事件编写一些

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

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

选项1的更详细说明

表格

概述
ID
概述

规则
ID
规则

关系
规则SID)由两个FK形成的PK
概览ID)

关系

数据

建议1查询设计

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

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

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

如果更新
RulesID
OverviewID
,则会将记录添加到关系表中,但不会添加到规则中

如果更新了
概览ID
规则
,记录将同时添加到关系和规则中

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


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

如果所讨论的键是一个自动编号(
IDENTITY
),并且一个表引用另一个表(通过外键),那么您可以创建一个连接两个表的
视图,插入到视图中,并且自动编号值会自动复制到引用表中。下面是一个快速演示:

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

谢谢你的回复,雷蒙。我试图利用数据表视图的使用,因为似乎所有的操作(插入/更新/删除)都可以通过它来完成。我的设置听起来与您在第一段中提到的完全相同,其中数据表视图中显示的记录基于组合框中选择的概述类型。因此,当插入发生在子窗体/数据表中时,您是否认为插入后的
将是一个很好的位置在
关系表中插入一个新行?我已经使用插入后的
使它工作了。我会为任何其他有此问题的人提供一个pastebin链接,但它在工作中被阻止。@Mitch没有必要编写任何代码来完成您想做的事情。请看上面。感谢您的详细编辑。几个问题:1)您已经在
关系表中创建了外键
主键-如果外键已设置为“索引(重复项OK)”,是否有必要?2) 除了
关系表中的主键标记,我的表的关系与您发布的表的关系相同。您说过,如果我更新OverviewID和Rule,记录将同时添加到关系和规则中,但这并不是我真正想要的-用户不应该这样做。我希望能够将一条记录添加到
规则
,并将其传播到
关系
。3)至于连续形式,我很确定我已经有了。我有一个
规则
表的数据表视图,该视图仅显示在关系表中具有匹配概述的规则,该概述与用户从概述组合框(不显示ID)中选择的内容相同。对于我来说,这是否适用于Remou发布的表结构,目前还不清楚(这是我的一个简化描述)。@Mitch:你的规范说,当你在
规则
表中插入一条记录时,你希望一个匹配的行自动插入到关系
表中
。这可以通过我发布的模型实现(当然,我更改了表名)。但是,使用@Remou的模型(引用),“您需要创建所有概述,然后才能工作,或者提供一种不同的添加概述的方法。”我选择回答您的问题,而不是基于@Remou的答案;)@Mitch:我已经更新了代码示例,以使用@Remou答案中的元数据,为演示目的添加了一个属性
关系.Name
。如果您的PK是自动编号字段,则将级联更新设置为“自动编号”没有任何作用