【问题标题】:MS Access set cascade-to-null constraint to existing tableMS Access 对现有表设置 cascade-to-null 约束
【发布时间】:2012-04-30 16:04:41
【问题描述】:

使用由 vb.net 应用程序访问的 MS Acess 2007 数据库 我有两个现有的表

Members
-------
ID     name     bandID
-----------------------
0      Pierre   1
1      Chart    3
2      John     3
3      Dave     2  

Bands
-----
ID     bandName
----------------
1      Band a
2      Band b
3      Band c

我想为 members.bandId 和bands.ID 之间的关系添加一个级联到空约束

这就是我所拥有的

ALTER TABLE members ADD CONSTRAINT membresBands_FK
    FOREIGN KEY (bandID) REFERENCE Bands(ID) ON DELETE CASCADE SET NULL

但我收到此错误消息:

CONSTRAINT 子句中的语法错误

从我找到的msdn

CREATE TABLE Orders 
  (OrderId INTEGER PRIMARY KEY, 
  CustId INTEGER, 
  OrderNotes NCHAR VARYING (255), 
  CONSTRAINT FKOrdersCustId FOREIGN KEY (CustId) 
  REFERENCES Customers ON UPDATE SET NULL ON DELETE SET NULL

是否可以更改 MS Access 中的表以将级联关系设置为空?

谢谢!

【问题讨论】:

  • 你在混淆你的条款。 CASCADESET NULL 是不同的引用操作。

标签: sql ms-access relationship


【解决方案1】:

可以在 Access 中创建这种约束,但只能通过 Jet OLE DB Provider 和 ADO。例如,对于 Access 中的数据库,您可以通过运行以下 VBA 代码来创建约束:

CurrentProject.Connection.Execute "ALTER TABLE membres ADD CONSTRAINT membresBands_FK FOREIGN KEY (bandID) REFERENCES bands(ID) ON DELETE SET NULL"

【讨论】:

  • 我刚刚使用 vb 模块解决了我的问题,如 link 所示。我会看看你的建议。
  • 我尝试了你的建议,但得到了同样的错误信息。我的查询可能有问题。
  • 您尝试了我发布的查询,还是尝试了原始消息中发布的查询?我问的原因是,在您原始消息中发布的查询中,REFERENCE 应该是REFERENCES。无论如何,我很高兴您以某种方式找到了解决方案。
  • 我使用 Visual Basic 模块尝试了您的查询。经过一番思考,我不确定这是否真的使用了 Jet OLE DB 和 ADO
  • “您可以在 Access 中创建这种约束,但只能通过 Jet OLE DB Provider 和 ADO”——不太正确。使用 Access XP 或更高版本,可以将 Access UI 置于 ANSI-92 查询模式以运行相同的 SQL DLL。 This article 演示了如何使用 DAO 代码实现相同的目标。
【解决方案2】:

我不得不等待八小时才能发布这个...

使用 Visual Basic 模块

'Define the bit value for the relation Attributes.
Public Const dbRelationCascadeNull As Long = &H2000

Public Function MakeRel()
    'Purpose: Create a Cascade-to-Null relation using DAO.
    Dim db As DAO.Database
    Dim rel As DAO.Relation
    Dim fld As DAO.Field

    Set db = CurrentDb()
    'Arguments for CreateRelation(): any unique name, primary table, related table, attributes.
    Set rel = db.CreateRelation("membre_bands", "bands", "membres", dbRelationCascadeNull)
    Set fld = rel.CreateField("ID")  'The field from the primary table.
    fld.ForeignName = "band"           'Matching field from the related table.
    rel.Fields.Append fld                    'Add the field to the relation's Fields collection.
    db.Relations.Append rel                  'Add the relation to the database.


    'Report and clean up.
    Debug.Print rel.Attributes
    Set db = Nothing
End Function

然后调用 MakeRel 函数

http://allenbrowne.com/ser-64.html找到的函数

【讨论】:

    【解决方案3】:

    AFAIK,Access 中没有 Cascade to Null。只有Cascade DeleteCascade Update

    【讨论】:

    • 来自 msdn: 级联操作也可以通过使用外键关系对话框来定义:[ ON DELETE { NO ACTION |级联 |设置空 |设置默认值 } ] [ 更新时 { 无操作 |级联 |设置空 |设置默认值}]
    • +1,我看到了 Brian 的回复和你的 cmets。我从来没有发现过!
    【解决方案4】:

    各种 DBMS 中的级联效果选项有:

    ON DELETE SET NULL

    ON DELETE CASCADE

    ON DELETE RESTRICT

    ON DELETE NO ACTION

    我认为 MS-Access 有前两个。所以,应该是:

    ON DELETE SET NULL

    【讨论】:

    • 我试过:ALTER TABLE membres ADD CONSTRAINT membresBands_FK FOREIGN KEY (band) REFERENCE Bands(ID) ON DELETE SET NULL 我得到了同样的错误信息
    • 毫不奇怪,它还支持ON DELETE NO ACTION 并且是默认选项——强制用户在前两个之间进行选择是最奇怪的:) p.s. “级联效应”具有误导性(可以说只有其中一个是“级联效应”);标准 SQL 术语是“引用触发操作”(SET NULL 是“引用操作”的一个示例)。
    【解决方案5】:

    docs for Access 表示它支持以下引用触发操作:

    ON DELETE CASCADE
    ON UPDATE CASCADE
    ON DELETE SET NULL
    ON UPDATE SET NULL
    

    ...但是,实际上它只支持前三个,即不支持ON UPDATE SET NULL。为了进一步澄清,引擎根本不支持 ON UPDATE SET NULL 引用触发操作,即不仅仅是 DDL 语法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多