SQL-Oracle07sql约束(二)

2014-11-24 16:29:12 · 作者: · 浏览: 1
LT '男',
CONSTRAINT person_pid_pk PRIMARY KEY(pid),
CONSTRAINT person_name_uk UNIQUE(name),
CONSTRAINT person_age_ck CHECK(age BETWEEN 0 AND 150),
CONSTRAINT person_sex_ck CHECK(sex IN('男','女','中'))
) ;

再次插入错误的年龄:
INSERT INTO person(pid,name,age,birthday,sex)VALUES
('111111111111111111','张三',300,TO_DATE('1976-02-13','yyyy-mm-dd'),'女') ;

第1行出现错误:
ORA-02290:违反检查约束条件(SCOTT.PERSON_AGE_CK)

再次插入错误性别:

INSERT INTO person(pid,name,age,birthday,sex)VALUES
('111111111111111111','张三',300,TO_DATE('1976-02-13','yyyy-mm-dd'),'JGH') ;

第1行出现错误:
ORA-02290:违反检查约束条件(SCOTT.PERSON_SEX_CK)
======================
======================
======================
主外键约束(FOREIGN KEY)

针对两张表的约束。

eg:要求完成一个程序,一本书属于一个人。
书本身应该是一张表,一个书中必然有一个字段表示属于哪个人的
CREATE TABLE person
(
pid varchar2(18) ,
name varchar2(200) NOT NULL ,
age number(3) NOT NULL ,
birthday DATE ,
sex varchar2(2) DEFAULT '男',
CONSTRAINT person_pid_pk PRIMARY KEY(pid),
CONSTRAINT person_name_uk UNIQUE(name),
CONSTRAINT person_age_ck CHECK(age BETWEEN 0 AND 150),
CONSTRAINT person_sex_ck CHECK(sex IN('男','女','中'))
) ;

CREATE TABLE book
(
bid NUMBER PRIMARY KEY NOT NULL ,
bname VARCHAR(30) ,
bprice NUMBER(5,2) ,
pid VARCHAR2(18) ,
CONSTRAINT person_book_fk FOREIGN KEY(pid) REFERENCES person(pid)
) ;

先创建两张表,然后插入一些测试数据:
INSERT INTO person(pid,name,age,birthday,sex)VALUES
('111111111111111111','张三',30,TO_DATE('1976-02-13','yyyy-mm-dd'),'女') ;
INSERT INTO book(bid,bname,bprice,pid) VALUES
(1,'JAVA SE',89.9,'111111111111111111') ;

确实可符合要求

但是若写为:

INSER INTO book(bid,bname,bprice,pid) VALUES
(2,'JAVA SE',89.9,'000000000000000000') ;

此编号的人员并不存在,则此数据肯定不能被插入。(因为没有此书对应的人,但是不设置外键约束,则可以插入书)
此时,如果要想解决这样的问题,则肯定要使用主外键关联,关联之后子表的数据要跟随父表的数据内容。

INSERT INTO book(bid,bname,bprice,pid) VALUES
(2,'JAVA SE',89.9,'000000000000000000') ;

违反完整约束条件(SCOTT.PERSON_BOOK_PID_FK)-未找到父项关键字

此时,可以保证两张表的数据的完整性,不会出现找不到对应数据的情况。
在使用主-外键关联的时候也要有以下注意点:
在子表中设置的外键在父表中必须是主键

删除时应该先删除子表,在删除父表
DROP TABLE person ;
DROP TABLE book ;

错误:
表中的唯一/主键被外键引用

DROP TABLE book ;

ORA-02289:表已删除,

说明现在根本无法删除子表,因为存在这样的关联关系。

DROP TABLE book ;
DROP TABLE person ;

此时可以使用强制性的删除手段
(级联删除约束)
DROP TABLE book CASCADE CONSTRAINT ;
不管约束,而直接删除,但是这种做法一般不使用。

回顾:

emp和dept表,实际上这两张表也是有主-外键关联的。
eg:现在向emp表中增加一个50部门的员工
在dept表中本身并不存在50部门的部门编号

INSERT INTO emp(empno,ename,job,sal,mgr,hiredate,comm,deptno)
VALUES (8888,'张三','经理',90000,null,sysdate,null,50) ;

ORA-02291:违反完整约束条件(SCOTT.FK_DEPTNO)-未找到父项关键字

在主-外键关联中可以使用级联删除的情况。

以现在数据库中的数据为例 .

INSERT INTO emp(empno,ename,job,sal,mgr,hiredate,comm,deptno)
VALUES (8888,'','',90000,null,sysdate,null,50) ;

DELETE FROM person WHERE pid='111111111111111111';

要删除person表中标号为“111111111111111111”的人员,
但是此人员现在在book表中存在一本书。

SQL>DELETE FROM person WHERE pid='111111111111111111' ;
DELETE FROM person WHERE pid='111111111111111111' ;
*
第1行出现错误:
ORA-02292:违反完整约束条件(SCOTT.PERSON_BOOK_PID_FK)-已找到子记录

因为在子表中存在此项的关联,所以无法删除,那么,此时如果要想完成
删除操作的话,则必须先将book表中对应的数据删除掉。

如果希望一个表中的数据在删除时,可以自动删除掉其对应的子表记录,
则就可以使用级联删除的操作。

CREATE TABLE book
(
bid NUMBER PRIMARY KEY NOT NULL ,
bname VARCHAR(30) ,
bprice VARCHAR(5,2) ,
pid VARCHAR2(18) ,
CONSTRAINT person_book_pid_fk FOREIGN KEY(pid) REFERENCES person(pid) ON DELETE CASCADE
) ;

更改表结构之后,之后再次执行删除操作

----------------
----------------
----------------
修改约束

如果一张表已经建立完成以后,可以为其添加约束。

DROP TABLE p