约束
约束
一个字段可以有多个约束(前提不冲突)
什么是约束?
给表增加规则和条件(限制)。
约束的作用:
可以让表更加符合实际要求。因为约束具有不符合条件的数据不予录入的特点。
约束的分类:
列级约束(六种):主键(PRIMARY KEY),外键(FOREIGN KEY),唯一(UNIQUE),检查(CHECK),非空(/空值)(NOT NULL/NULL) ,默认(DEFAULT)
表级约束(四种):主键(PRIMARY KEY),外键(FOREIGN KEY),唯一(UNIQUE),检查(CHECK)
(主键=非空+唯一)
列级约束和表级约束的区别:
当一个约束只约束一个列时,他是列级约束;
当一个约束同时约束多个列时,他是表级约束;
一、非空约束 (NOT NULL/NULL)
1.可以在创建表的时候创建非空约束
语法:CREATE TABLE
表名 (字段1 数据类型 NULL
,字段2 数据类型 NOT NULL
,…)
–限制可以为空值写不写NULL
影响不大
1 | CREATE TABLE EMP3(EMPNO NUMBER(4) NULL,DEPTNO NUMBER(2) NOT NULL,SAL NUMBER(10)); |
特点:
- NULL可以省略的,隐藏的默认值
- 插入违反约束条件的数据会报错
- 只能影响一个列,是列级约束,没有表级约束
- 如果列内有空值,约束不能改成非空
2.给表新增字段时,同时建立非空约束
语法:ALTER TABLE
表名 ADD
(字段1 数据类型 NULL
/NOT NULL
,…)
1 | ALTER TABLE EMP3 ADD(ENAME VARCHAR2(10) NOT NULL);--报错,在新增列的时候,下面的数据为空,与非空约束冲突 |
3.给已有字段建立非空约束
语法:ALTER TABLE
表名 MODIFY
(字段1 NOT NULL
/NULL
);
1 | 修改数据类型 |
拓展:
约束能不能修改成自己?
1
ALTER TABLE EMP3 MODIFY(SAL NULL);--不能
能否新增一个同名列,约束不同?
1
ALTER TABLE EMP3 ADD(SAL NUMBER NULL);--不能创建同名列
CONSTRAINT
–起约束名的关键词
约束名的起名规则:约束名_表名_列名
注意:
- 同一个用户下,约束名不能重复
- 同一个用户下,表名不能重复
- 同一个表中,列名不能重复
1 | SELECT * FROM EMP3; |
二、唯一约束 UNIQUE
同一列内数据不能重复
1.可以在创建表的时候创建唯一约束
CREATE TABLE
表名(字段1 数据类型 CONSTRAINT
约束名1 UNIQUE
,字段2 数据类型 CONSTRAINT
约束名2 UNIQUE
,…);–列级约束
1 | CREATE TABLE EMP3(EMPNO NUMBER(4) CONSTRAINT UNI_EMP_EMPNO UNIQUE); |
CREATE TABLE
表名(字段1 数据类型,字段2 数据类型,…,CONSTRAINT
约束名 UNIQUE
(字段1,字段2,…))–表级约束
1 | CREATE TABLE EMP3(EMPNO NUMBER,DEPTNO NUMBER ,CONSTRAINT UNI_EMP UNIQUE (EMPNO,DEPTNO)); |
–当表级约束约束多个列时,多个列为一个整体,有一个不一样都算不一样
–约束名能否取一样的名字
1 | SELECT * FROM EMP3; |
–一个表内可以插入不同的约束
1 | ALTER TABLE EMP3 ADD(ENAME VARCHAR2(10) CONSTRAINT UNI_EMP_EMPNO UNIQUE); |
–同一个表内,约束名不能重复
1 | CREATE TABLE EMP1 AS SELECT * FROM EMP; |
–同一个用户下,约束名不能重复
2.给表新增字段时,同时建立非空约束
语法:ALTER TABLE
表名 ADD
(字段1 数据类型 CONSTRAINT
约束名 UNIQUE
);–列级约束
==列级约束==
ALTER
TABLE
表名 ADD
(字段1 数据类型 CONSTRAINT
约束名1 UNIQUE
,字段2 数据类型 CONSTRAINT
约束名2 UNIQUE
,…);
1 | ALTER TABLE EMP3 ADD(JOB VARCHAR2(10) CONSTRAINT UNI_EMP_JOB UNIQUE); |
==表级约束==
ALTER
TABLE
表名 ADD
(字段1 数据类型,字段2 数据类型,..,CONSTRAINT
约束名 UNIQUE
(字段1,字段2,…));
1 | ALTER TABLE EMP3 ADD(SAL NUMBER(10),MGR NUMBER(10), CONSTRAINT UNI_EMP UNIQUE(SAL,MGR)); |
3.给已有字段建立唯一约束
==列级约束==
ALTER
TABLE
表名 MODIFY
(字段1 数据类型 CONSTRAINT
约束名 UNIQUE
,字段2 数据类型 CONSTRAINT
约束名 UNIQUE
,…);
1 | ALTER TABLE EMP3 MODIFY(SAL NUMBER(10) CONSTRAINT UNI_EMP_JOBB UNIQUE); |
==表级约束==
ALTER
TABLE
表名 MODIFY
(字段1 数据类型,字段2 数据类型,..,CONSTRAINT
约束名 UNIQUE
(字段1,字段2,…));
1 | ALTER TABLE EMP2 MODIFY(EMPNO NUMBER(4),DEPTNO NUMBER(2),CONSTRAINT UNI_EMP2 UNIQUE(EMPNO,DEPTNO)); |
问:能否将数据类型去掉?–可以
1 | ALTER TABLE EMP2 MODIFY(COMM CONSTRAINT UNI_EMP2_COMM UNIQUE); |
三、主键约束 PRIMARY KEY
主键=非空+唯一 –说明里面既不能为空值,也不能有重复的值
1.在创建表的时候创建主键约束
/==列级约束==/
CREATE
TABLE
表名(字段1 数据类型 CONSTRAINT
约束名1 PRIMARY
KEY
);
1 | CREATE TABLE EMP3(EMPNO NUMBER(10) CONSTRAINT PK_EMP3_EMPNO PRIMARY KEY,DEPTNO NUMBER(10) CONSTRAINT UNI_EMP3_DEPTNO unique); |
一个表内只能创建一个主键约束
一个语句里面可以同时创建不同的约束
问:1.一个列上只能有一个约束吗?–不是
2.如果只能有一个主键约束,为什么会有表级约束呢?
==表级约束==
CREATE
TABLE
表名(字段1 数据类型,字段2 数据类型,…,CONSTRAINT
约束名 PRIMARY
KEY
(字段1,字段2,…))
1 | CREATE TABLE EMP3(EMPNO NUMBER(10),DEPTNO NUMBER(10), CONSTRAINT PK_EMP3 PRIMARY KEY(EMPNO,DEPTNO)); |
2.给表新增字段时,同时建立主键约束
==列级约束==
ALTER TABLE 表名 ADD(字段1 数据类型 CONSTRAINT 约束名1 PRIMARY KEY);
1 | ALTER TABLE EMP3 ADD(JOB VARCHAR2(10) CONSTRAINT UNI_EMP_JOB PRIMARY KEY); |
==表级约束==
ALTER TABLE 表名 ADD(字段1 数据类型,字段2 数据类型,.. CONSTRAINT 约束名 PRIMARY KEY(字段1,字段2,…));
1 | ALTER TABLE EMP3 ADD(SAL NUMBER(10),MGR NUMBER(10) CONSTRAINT UNI_EMP PRIMARY KEY(SAL,MGR)); |
3.给已有字段建立主键约束
==列级约束==
ALTER TABLE 表名 MODIFY(字段1 数据类型 CONSTRAINT 约束名 PRIMARY KEY);
1 | ALTER TABLE EMP3 MODIFY(SAL NUMBER(10) CONSTRAINT UNI_EMP_JOBB UNIQUE); |
==表级约束==
ALTER TABLE 表名 MODIFY(字段1 数据类型,字段2 数据类型,..,CONSTRAINT 约束名 PRIMARY KEY(字段1,字段2,…));
1 | ALTER TABLE EMP2 MODIFY(EMPNO NUMBER(4),DEPTNO NUMBER(2),CONSTRAINT UNI_EMP2 PRIMARY KEY(EMPNO,DEPTNO)); |
MODIFY不是修改约束,而是增加约束
主键约束不能和唯一约束创建在同一个列上,但是能和非空约束创建在同一个列上
一个列上能有多个约束
四、检查约束
是给字段制定一个范围,插入数据时,会先检查是否符合范围,符合才能插入。
注意检查约束中不能使用子查询
1.在创建表的时候创建检查约束
语法:
==列级约束==
CREATE TABLE 表名 (字段1 数据类型 CONSTRAINT 约束名1 CHECK(范围1),字段2 数据类型 CONSTRAINT 约束名2 CHECK(范围2),…)
1 | CREATE TABLE EMP3 (EMPNO NUMBER(10,2) CONSTRAINT CH_EMP3_EMPNO CHECK(EMPNO<30)); |
==表级约束==
CREATE TABLE 表名(字段1 数据类型,字段2 数据类型,…,CONSTRAINT 约束名 CHECK(范围1,范围2,..,))
1 | CREATE TABLE EMP3(EMPNO NUMBER(4),DEPTNO NUMBER(2),CONSTRAINT CH_EMP3 CHECK(EMPNO < 30 AND DEPTNO>30)); |
2.给表新增字段时,同时建立检查约束
==列级约束==
ALTER TABLE 表名 ADD(字段1 数据类型 CONSTRAINT 约束名1 CHECK(范围1),字段2 数据类型 CONSTRAINT 约束名2 CHECK(范围2),…);
1 | ALTER TABLE EMP3 ADD(SAL NUMBER(10) CONSTRAINT CH_EMP3_SAL CHECK(SAL BETWEEN 1000 AND 3000)); |
==表级约束==
ALTER TABLE 表名 ADD(字段1 数据类型,字段2 数据类型,..,CONSTRAINT 约束名 CHECK(范围1,范围2,…));
1 | ALTER TABLE EMP3 ADD(SEX VARCHAR2(3),SSEX VARCHAR2(9), CONSTRAINT CH_EMP33 CHECK(SEX IN ('男','女') OR SSEX= '中间人')); |
3.给已有字段建立检查约束
==列级约束==
ALTER
TABLE
表名 MODIFY
(字段1 数据类型 CONSTRAINT
约束名 CHECK
(范围1),字段2 数据类型 CONSTRAINT
约束名 CHECK
(范围2),…);
1 | ALTER TABLE EMP3 MODIFY(COMM NUMBER(10) CONSTRAINT CH_EMO3_COMM CHECK(COMM IS NOT NULL));--试试这种情况 |
==表级约束==
ALTER TABLE 表名 MODIFY(字段1 数据类型,字段2 数据类型,..,CONSTRAINT 约束名 CHECK(范围1,范围2,…));
1 | ALTER TABLE EMP2 MODIFY(EMPNO NUMBER(4),DEPTNO NUMBER(2),CONSTRAINT CH_EMP2 CHECK(EMPNO>0 AND DEPTNO<=40)); |
五、外键约束 FOREIGN KEY
指当前列一定得从其他表中的主键或者唯一列上获取参照物
EMP表中的DEPTNO列,只能输入10,20,30,40,这些值从DEPT表中的DEPTNO列获取
1.在创建表的时候创建外键约束
语法:
==列级约束==
CREATE
TABLE
表名 (字段1 数据类型 , CONSTRAINT
约束名1 FOREIGN
KEY
(外键列的字段名) REFERENCES
参照表(参照列));
1 | CREATE TABLE EMP3(DEPTNO NUMBER(2),CONSTRAINT FK_EMP3_DEPTNO FOREIGN KEY(DEPTNO) REFERENCES EMP(SAL)); |
1.参照列一定是其他表内的主键或者唯一列,外键列不需要是唯一或者主键列
2.插入的值只能是参照物里面的内容
3.外键约束在数据类型后面==有逗号==
==表级约束==CREATE
TABLE
表名 (字段1 数据类型 ,字段2 数据类型, CONSTRAINT
约束名 FOREIGN
KEY
(外键列的字段名1,字段名2) REFERENCES
参照表(参照列1,参照列2));
1 | CREATE TABLE EMP3(ENAME NUMBER(4),JOB NUMBER(4),CONSTRAINT FK_EMP3 FOREIGN KEY(ENAME,JOB) REFERENCES EMP(EMPNO,SAL)); |
注意:
4.外键列和参照列名字可以不一样,数据类型必须保持一致
5.表级外键的参照列必须也是表级的
2.给表新增字段时,同时建立外键约束
==列级约束==
ALTER
TABLE
表名 ADD
(字段1 数据类型 ,CONSTRAINT
约束名1 FOREIGN
KEY
(外键列的字段名1) REFERENCES
参照表(参照列));
==表级约束==ALTER
TABLE
表名 ADD
(字段1 数据类型 ,字段2 数据类型, CONSTRAINT
约束名 FOREIGN
KEY
(外键列的字段名1,字段名2) REFERENCES
参照表(参照列1,参照列2));
3.给已有字段建立外键约束
==列级约束== ALTER
TABLE
表名 MODIFY
(字段1 数据类型 ,CONSTRAINT
约束名1 FOREIGN
KEY
(外键列的字段名1) REFERENCES
参照表(参照列));
==表级约束==ALTER
TABLE
表名 MODIFY
(字段1 数据类型 ,字段2 数据类型, CONSTRAINT
约束名 FOREIGN
KEY
(外键列的字段名1,字段名2) REFERENCES
参照表(参照列1,参照列2));
六、默认约束 DEFAULT
当给表插入一行数据时,含有默认约束的列如果没有插入数据,会用默认值自动填充
不能起约束名
不能用删除约束的方法对待默认值
1.建表的同时建立默认约束
语法:
==列级约束==
CREATE
TABLE
表名(字段1 数据类型 DEFAULT
(默认值1),字段2 数据类型 DEFAULT
(默认值2),…);
1 | CREATE TABLE EMP3(EMPNO NUMBER(4),SEX VARCHAR2(3) DEFAULT ('男')); |
==默认约束没有表级约束==
2.给表新增字段时,同时建立默认约束
ALTER
TABLE
表名 ADD
(字段1 数据类型 DEFAULT
(默认值1),字段2 数据类型 DEFAULT
(默认值2),…);
3.给已有字段建立默认约束
ALTER
TABLE
表名 MODIFY
(字段1 数据类型 DEFAULT
(默认值1),字段2 数据类型 DEFAULT
(默认值2),…);
默认值的==修改==方式ALTER
TABLE
表名 MODIFY
(字段1 数据类型 DEFAULT
(默认值1),字段2 数据类型 DEFAULT
(默认值2),…);
–问题:现在是在之前的基础上增加限制,还是进行修改呢?
默认值的==删除==方式ALTER
TABLE
表名 MODIFY
(字段1 数据类型 DEFAULT
(‘’));
1 | ALTER TABLE 表名 MODIFY(字段1 数据类型 DEFAULT (NULL));--这个会不会报错? |
七、其他
1.删除约束的方法
补充:删除列
ALTER
TABLE
表名DROP
COLUMN
列名
ALTER
TABLE
表名 DROP
CONSTRAINT
约束名;
删除表的==单个==字段约束
1 | ALTER TABLE 表名 DROP UNIQUE(字段名); |
删除表的==多个==字段约束
1 | ALTER TABLE 表名 DROP CONSTRAINT 约束名; |
2.约束重命名
表的重命名 :ALTER TABLE 旧表名 RENAME TO 新表名;
列的重命名:ALTER TABLE 表名 RENAME COLUMN 旧列名 TO 新列名;
ALTER
TABLE
表名 RENAME
CONSTRAINT
旧约束名 TO
新约束名;
3.约束禁用 DISABLE
ALTER
TABLE
表名 DISABLE
CONSTRAINT
约束名;
4.约束启用 ENABLE
ALTER
TABLE
表名 ENABLE
CONSTRAINT
约束名;
- 在约束被禁用后,如果插入了不符合约束的数据,无法再启用约束
- 唯一或者主键被外键引用时,无法直接删除带有唯一或主键的表,需要先删除外键约束。
给表的单个字段加约束
1 | ALTER TABLE 表名 ADD UNIQUE(字段名); |
1 | ALTER TABLE 表名 ADD CONSTRAINT 约束名 UNIQUE (字段名, 字段名 ...); |
查询某表都有哪些约束
1 | select CONSTRAINT_NAME from USER_CONSTRAINT WHERE TABLE_NAME=表名 AND CONSTRAINT_TYPE=U; |
查询某约束都约束了哪些字段
1 | select COLUMN_NAME from USER_CONS_COLUMN WHERE CONSTRAINT_NAME=约束名; |