访问 SQL 以创建一对多关系而不强制参照完整性

Posted

技术标签:

【中文标题】访问 SQL 以创建一对多关系而不强制参照完整性【英文标题】:Access SQL to create one-to-many relation without Enforce Referential Integrity 【发布时间】:2015-05-05 02:02:29 【问题描述】:

我有这种关系。而且我必须暂时销毁它只是为了使用 SQL 命令更改“salID”字段的大小:

ALTER TABLE Adressen DROP CONSTRAINT [ChildTableMainTable]

如何使用 SQL 命令重新创建相同的关系类型? 如果我使用下一个 SQL,我会得到一个一对多的关系。这不是我需要的:

ALTER TABLE MainTable ADD CONSTRAINT [ChildTableMainTable] FOREIGN KEY (salID) REFERENCES [ChildTable] (ChildPK);

【问题讨论】:

我认为,这两种关系都是一对多的关系,如底部的编辑关系框中所示......您可能正在寻找的是在末尾附加ON UPDATE SET NULL ON DELETE SET NULL?跨度> 在我的原始关系中未检查强制参照完整性。在不同的方法之后我放弃了。 如果你想要这些表之间没有参照完整性的一对多关系,除了加入 salID 和 CliIDPK 之外,我想不出别的了, 我正在更新一个旧产品,这需要对具有关系的字段进行一些修改。这些关系使我们更容易访问和查看查询中的数据。但是古老而糟糕的数据库设计不适用于强制关系。理想情况下,我宁愿只运行一个脚本来更新所述数据库,而不是有一堆手动步骤或编写一个单独的应用程序。我知道 DAO 可用于自动执行此操作,但这是一堆额外的工作(每次更改的代码段)实际上应该只是 SQL 中的一个关键字(例如 NOCHECK)。 @Simoyd:如果你修改Gord的函数,将表名和字段名作为参数,每个关系只有一行代码。 【参考方案1】:

据我所知,Access DDL 根本不支持在没有“强制参照完整性”的情况下创建访问“关系”。 CREATE CONSTRAINT 将创建一个关系with“强制参照完整性”,因为这正是这种关系的本质:参照完整性约束

CREATE CONSTRAINTON UPDATEON DELETE 子句控制“编辑关系”对话框中“级联更新相关字段”和“级联删除相关记录”复选框的值,但它们不控制“强制参照完整性”复选框本身。)

换句话说,没有“强制参照完整性”的关系根本不是约束。表通过指定字段关联只是一个“提示”,例如,如果将表添加到查询设计中,查询构建器可以自动连接表。

要创建没有“强制参照完整性”的关系,您需要使用 Access DAO。对于这样的关系

VBA 中所需的代码是

Option Compare Database
Option Explicit

Public Sub CreateRelationship(relationshipName As String, _
        parentTableName As String, childTableName As String, _
        parentTablePkName As String, childTableFkName As String)
    Dim cdb As DAO.Database
    Set cdb = CurrentDb
    Dim rel As DAO.Relation
    Set rel = cdb.CreateRelation(relationshipName, parentTableName, _
            childTableName, dbRelationDontEnforce)
    rel.Fields.Append rel.CreateField(parentTablePkName)  ' parent PK
    rel.Fields(parentTablePkName).ForeignName = childTableFkName  ' child FK
    cdb.Relations.Append rel
    Set rel = Nothing
    Set cdb = Nothing
End Sub

【讨论】:

【参考方案2】:

首先,您的“Cihld”(真的有人拼错 Child 并将其留在架构中吗???)表实际上是 parent 表,而 Main 表是 子表,根据定义的关系:子表的外键列被限制为具有来自父表的主键值。这种混淆,加上拼写错误,强烈暗示一团糟。

尽管如此,允许将外键列定义为可为空的(即使用NOT NULL 修饰符定义它们)。执行此操作,只需将外键列设置为 NULL 您不希望限制回父表的任何行。

【讨论】:

以上是关于访问 SQL 以创建一对多关系而不强制参照完整性的主要内容,如果未能解决你的问题,请参考以下文章

访问 2007 引用完整性而不使用表中的查找

access 不能建立删除查询。

SQLite 是不是支持参照完整性?

SQL - 多个一对多关系

SQL 中的参照完整性完整性检查

将带有连接的 SQL 查询转换为 lambda 表达式