我是一名学生,目前正在学习SQL编码,由于某种原因,我似乎不能得到这个错误。
CREATE TABLE CUSTOMER
(
id CHAR(9) NOT NULL,
CustomerName CHAR(50) NOT NULL,
Address VARCHAR(100) NOT NULL,
Contact CHAR(8) NOT NULL,
DateofBirth DATE NOT NULL,
Occupation VARCHAR(30) NOT NULL,
CONSTRAINT CUSTOMER_PK
PRIMARY KEY(id),
ON UPDATE CASCADE
ON DELETE CASCADE -- default if not specify
CONSTRAINT CHECK (ID LIKE '[ST][0-9][0-9][0-9][0-9][0-9][0-9][0-9][A-Z]')
CONSTRAINT CHECK (YEAR(GETDATE()) - YEAR(dateofBirth) > 21)
);
我得到这个错误:
Msg 156,第15层,状态1,第42行
关键字'ON'附近语法错误
ON UPDATE CASCADE
和ON DELETE CASCADE
选项适用于外键,而不是主键。- 所以你指定的选项在其他表引用
CUSTOMER
,而不是在CUSTOMER
表本身。 - 也就是说,主键应该是不可变的(即它们永远不会改变),所以如果你发现自己需要使用
ON UPDATE CASCADE
,那么可能是你的数据库设计有问题。 - 然而,使用
ON DELETE CASCADE
是可以的。(只是要确保你有备份,所以你不会意外核你的整个数据库,当你删除一行在一个复杂的对象图,整个事情级联…)
- 所以你指定的选项在其他表引用
- 也,这是错误的:
CONSTRAINT CHECK (YEAR(GETDATE()) - YEAR(dateofBirth) > 21)
我想这是为了确保客户的"年龄"。是大于21-但是它实际做的是检查是否22(不是21)两个日期之间的年份,例如,如果某人出生在2000-12-31
而今天是2022-01-01
,那么这将不起作用。
同样,你应该命名你的约束,这样你就知道意味着要做什么。
相反,使用此技术从两个日期计算年龄。
要使用ON DELETE CASCADE或ON UPDATE CASCADE,必须与另一个(外部)表存在关系。
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name, ...)
REFERENCES tbl_name (col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
在您的情况下,似乎与任何其他表都没有关系。因此,您不需要这两个约束。
此外,不能在CHECK子句中使用Function或Expression。因此,您也必须排除Age验证。您可以使用插入/更新触发器来实现它。
CREATE TABLE CUSTOMER(
id Char(9) NOT NULL,
CustomerName CHAR(50) NOT NULL,
Address VARCHAR(100) NOT NULL,
Contact CHAR(8) NOT NULL,
DateofBirth DATE NOT NULL,
Occupation VARCHAR(30) NOT NULL,
CONSTRAINT CUSTOMER_PK PRIMARY KEY(id),
-- ON UPDATE CASCADE
-- ON DELETE CASCADE -- default if not specify
CONSTRAINT CHECK (ID LIKE '[ST][0-9][0-9][0-9][0-9][0-9][0-9][0-9][A-Z]')
-- CONSTRAINT CHECK (YEAR(GETDATE()) - YEAR(dateofBirth) > 21));
FOREIGN KEY Constraints
FOREIGN KEY Constraints w3schools reference
CHECK Constraints
CHECK Constraints w3schools reference
MySQL ON DELETE CASCADEPS:如果你正在使用SQL server,你可以改变你的SQL如下
CREATE TABLE CUSTOMER(
id Char(9) NOT NULL,
CustomerName CHAR(50) NOT NULL,
Address VARCHAR(100) NOT NULL,
Contact CHAR(8) NOT NULL,
DateofBirth DATE NOT NULL,
Occupation VARCHAR(30) NOT NULL,
CONSTRAINT CUSTOMER_PK PRIMARY KEY(id),
-- ON UPDATE CASCADE
-- ON DELETE CASCADE -- default if not specify
CONSTRAINT CHK_ID CHECK (ID LIKE '[ST][0-9][0-9][0-9][0-9][0-9][0-9][0-9][A-Z]'),
CONSTRAINT CKK_AGE CHECK (YEAR(GETDATE()) - YEAR(dateofBirth) > 21) );
您忽略了一个简单的要点:级联约束是在外键引用上,而不是在主键上。
原因很简单:您可能不希望所有的删除/更新都层叠进行。或者您可能希望它们以不同的方式级联。
因此,您的语法根本不属于customers
表。
如果您有另一个表,您可能会:
create table other (
. . .,
customerId int,
foreign key (customerId) references customers(id)
on delete cascade -- or whatever
);