如何为学生表的学号(ROLL_NO)属性创建正确的CHECK约束?
修正ROLL_NO的CHECK约束方案
先说说你原来的CHECK约束里的几个问题:
- 课程类型的匹配写法错误:
[M,P]会把逗号也当成合法字符,应该写成[MP]才能只匹配M或P - 数字序号的模式完全错误:
[01-99]不是合法的字符类写法,而且你要求序号从01开始、不能是00,所以得拆成两部分:先匹配两位数字,再排除00的情况 - 学号长度不匹配:你的规则是2位院系+1位类型+2位序号,总共5位,但你定义的
ROLL_NO是CHAR(7),长度对不上,得改成CHAR(5) - 注意:不同数据库对
LIKE的正则支持不一样,比如MySQL就不支持[A-Z]这种写法,得用正则表达式匹配
下面分不同数据库给出正确的建表语句:
1. SQL Server(支持LIKE的字符范围)
CREATE TABLE STUDENT ( ROLL_NO CHAR(5) PRIMARY KEY CHECK(ROLL_NO LIKE '[A-Z][A-Z][MP][0-9][0-9]' AND RIGHT(ROLL_NO, 2) <> '00'), NAME VARCHAR(20), ADDR VARCHAR(50), SMOB_NO BIGINT CHECK (SMOB_NO BETWEEN 1000000000 AND 9999999999), SU_EMAIL VARCHAR(20) );
这里用RIGHT(ROLL_NO, 2) <> '00'确保最后两位序号不是00,符合你从01开始的要求。
2. MySQL(需要用REGEXP代替LIKE)
MySQL的LIKE不支持[A-Z]这类字符类,得用正则表达式匹配;如果要强制匹配大写字母,可加上BINARY:
CREATE TABLE STUDENT ( ROLL_NO CHAR(5) PRIMARY KEY CHECK(BINARY ROLL_NO REGEXP '^[A-Z]{2}[MP][0-9]{2}$' AND RIGHT(ROLL_NO, 2) != '00'), NAME VARCHAR(20), ADDR VARCHAR(50), SMOB_NO BIGINT CHECK (SMOB_NO BETWEEN 1000000000 AND 9999999999), SU_EMAIL VARCHAR(20) );
3. PostgreSQL(用~进行正则匹配)
PostgreSQL用~匹配正则,同样可强制大写匹配:
CREATE TABLE STUDENT ( ROLL_NO CHAR(5) PRIMARY KEY CHECK(ROLL_NO ~ '^[A-Z]{2}[MP][0-9]{2}$' AND RIGHT(ROLL_NO, 2) <> '00'), NAME VARCHAR(20), ADDR VARCHAR(50), SMOB_NO BIGINT CHECK (SMOB_NO BETWEEN 1000000000 AND 9999999999), SU_EMAIL VARCHAR(20) );
另外顺便修正了一个小问题:你原来的SMOB_NO字段的CHECK约束里写错了字段名(写成了MOB_NO),上面的语句已经调整过来。
内容的提问来源于stack exchange,提问作者Manika Elizabeth Roy
相关产品推荐
相关产品推荐

