使用ON DELETE CASCADE定义表时出现语法错误

时间:2014-04-12 10:01:19

标签: ms-access ms-access-2007 constraints

我尝试在MS Access 2007中的FK约束中使用ON DELETE CASCADE,但我在表定义上遇到错误:

  

SQL错误:CONSTRAINT子句中的语法错误。

以下是创建表格的代码:

CREATE TABLE Area (
    Id AUTOINCREMENT PRIMARY KEY, 
    AreaType__Id int NOT NULL, 
    Tbl1 text(31) NOT NULL, 
    Tbl2__Id int NOT NULL, 
    CONSTRAINT UK_Area_1 UNIQUE (Tbl1, Container__Id), 
    CONSTRAINT FK_Area_1 FOREIGN KEY (AreaType__Id) REFERENCES AreaType (Id), 
    CONSTRAINT FK_Area_2 FOREIGN KEY (Tbl2__Id) REFERENCES Tbl2 (Id) ON UPDATE CASCADE ON DELETE CASCADE
);

我做错了什么?我查看了Access帮助,我的语法似乎正确。我尝试删除了ON UPDATE CASCADE部分,但收到了同样的错误。我还尝试使用引用表(REFERENCES Container而不是REFERENCES Container (Id))的默认PK字段,但同样出现了相同的错误。我也搜索了SO,但没有找到有关我情况的有用信息。它必须变得简单,但我现在还没有看到它。

修改

值得一提的是,除了没有ON UPDATE CASCADE ON DELETE CASCADE部分之外,表定义完全正常。只有在添加CASCADE部分后才会出现错误。

编辑2

为了查明问题,这里有一个新的测试代码,用于演示错误:

这项工作:

CREATE TABLE T1 (Id AUTOINCREMENT PRIMARY KEY);

CREATE TABLE T2 (
    Id AUTOINCREMENT PRIMARY KEY, 
    T1__Id int NOT NULL, 
    CONSTRAINT FK_T2_1 FOREIGN KEY (T1__Id) REFERENCES T1 (Id)
);

这给了错误:

CREATE TABLE T1 (Id AUTOINCREMENT PRIMARY KEY);

CREATE TABLE T2 (
    Id AUTOINCREMENT PRIMARY KEY, 
    T1__Id int NOT NULL, 
    CONSTRAINT FK_T2_1 FOREIGN KEY (T1__Id) REFERENCES T1 (Id) ON DELETE CASCADE
);

任何人都可以复制错误吗?

3 个答案:

答案 0 :(得分:5)

您的CREATE语句是有效的访问DDL,但必须与ADO一起执行。

这是一个立即窗口会话,演示了问题......

strSql = "CREATE TABLE T2 (" & vbCrLf & _
"    Id AUTOINCREMENT PRIMARY KEY, " & vbCrLf & _
"    T1__Id int NOT NULL, " & vbCrLf & _
"    CONSTRAINT FK_T2_1 FOREIGN KEY (T1__Id) REFERENCES T1 (Id) ON DELETE CASCADE" & vbCrLf & _
");"

' executing that statement with DAO triggers error 3289,
' "Syntax error in CONSTRAINT clause."
' (CurrentDb.Execute is a DAO Method)
CurrentDb.Execute strSql ' DAO -> fail

' CurrentProject.Connection.Execute is an ADO method,
' so this attempt executes without error
CurrentProject.Connection.Execute strSql ' ADO -> OK

注意,如果您尝试从Access查询设计器执​​行该语句,该语句也使用DAO,那么也会触发错误3289.

答案 1 :(得分:2)

OP的问题很久以前就已经解决了(参见HansUp的回答);但是,这个答案可能对其他人得到相同的错误信息很有用。

我遇到了同样的错误,因为我试图引用一个名为“User”的表。由于用户是一个保留字(显然),这失败了。解决方案是将保留名称括在括号中(ALTER TABLE UserSetting ADD CONSTRAINT FK_UserSetting_User FOREIGN KEY (UserID) REFERENCES [User] (UserID) ON DELETE CASCADE )。

int entierA8 = rnd.nextInt(10000 - 1) + 1;
        System.out.println("\n8.");
        do{
            entierA8 = rnd.nextInt(10000 - 1) + 1;
            System.out.println("Random number genrated: " + entierA8);
        }while();

答案 2 :(得分:1)

适用于我的参照完整性语法如下:

create table Area (
  ID autoincrement primary key
, AreaTypeID long not null
  constraint Area_AreaTypeID
  references AreaType (ID)
, Tbl1 varchar(31) not null
, Tbl2ID long not null
  constraint Area_Tbl2ID
  references Tbl2 (ID)
  on update cascade
  on delete cascade
, constraint Area_UK unique (
    Tbl1
  , ContainerID
  )
)

名称本身并不重要,但正如您所看到的,我避免给出与其他表名称相同的列,以避免混淆数据库引擎。

另外我要说的是,如果Tbl2 ID列是自动增量列,on update子句是多余的,因为显然数字ID永远不会改变。