我尝试在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
);
任何人都可以复制错误吗?
答案 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永远不会改变。