本文共 6936 字,大约阅读时间需要 23 分钟。
第十四章: 约束( Constraint)
1、约束的功能:通过一些强制性商业规则,保证数据的完整性、一致性
2、约束的类别:
1) not null 2) check 3) unique 4) primary key (not null + unique) 5) foreign key (reference) 3、约束的状态1) enable validate(默认) :约束会立刻生效,并对新旧数据都要符合约束
11:43:19 SQL> alter table emp1 11:44:19 2 enable validate constraint pk_emp1; alter table emp1 * ERROR at line 1: ORA-02437: cannot validate (SCOTT.PK_EMP1) - primary key violated -----新旧记录都必须符合约束 2) enable novalidate :约束会立刻生效,只检查新的数据,旧的数据可以不符合约束(注意对primary key 和unique,必须先建立非唯一性索引) 11:37:46 SQL> create table emp1 as select * from emp;Table created.
11:37:51 SQL> select * from emp1;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-DEC-80 800 20 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7566 JONES MANAGER 7839 02-APR-81 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30 7782 CLARK MANAGER 7839 09-JUN-81 2450 10 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7839 KING PRESIDENT 17-NOV-81 5000 10 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30 7876 ADAMS CLERK 7788 23-MAY-87 1100 20 7900 JAMES CLERK 7698 03-DEC-81 950 30 7902 FORD ANALYST 7566 03-DEC-81 3000 20 7934 MILLER CLERK 7782 23-JAN-82 1300 10 11:38:04 SQL> update emp1 set empno=7788 where ename='KING';1 row updated.
11:39:00 SQL> select * from emp1 WHERE EMPNO=7788;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7788 KING PRESIDENT 17-NOV-81 5000 1011:39:10 SQL>
---------添加primary key ,到enable novalidate
11:39:10 SQL> alter table emp1 add constraint 11:39:42 2 pk_emp1 primary key (empno) enable novalidate; pk_emp1 primary key (empno) enable novalidate * ERROR at line 2: ORA-02437: cannot validate (SCOTT.PK_EMP1) - primary key violated ---------原因:在建立primary key 它需要建立unique index---------在empno 上建立索引(非唯一性索引)
11:40:06 SQL> create index emp1_empno_ind on emp1(empno) tablespace indexes;Index created.
11:42:17 SQL> alter table emp1 add constraint
11:42:20 2 pk_emp1 primary key (empno) using index enable novalidate ;Table altered.
11:42:29 SQL>
--------新的记录必须符合约束,旧的不检查
11:42:58 SQL> update emp1 set empno=7788 where ename='FORD';
update emp1 set empno=7788 where ename='FORD' * ERROR at line 1: ORA-00001: unique constraint (SCOTT.PK_EMP1) violated3) disable validate:约束失效,但不能做DML操作
4) disable novalidate:约束失效,不检查任何数据(等于禁用约束) 4、修正约束(将违背约束的记录插入到exceptions表里)1)11:47:07 SQL> @?/rdbms/admin/utlexpt1
11:47:09 SQL> Rem 11:47:09 SQL> Rem $Header: utlexpt1.sql 24-jun-99.07:59:18 echong Exp $ 11:47:09 SQL> Rem 11:47:09 SQL> Rem utlexpt1.sql 11:47:09 SQL> Rem 11:47:09 SQL> Rem Copyright (c) Oracle Corporation 1998, 1999. All Rights Reserved. 11:47:09 SQL> Rem 11:47:09 SQL> Rem NAME 11:47:09 SQL> Rem utlexpt1.sql - <one-line expansion of the name> 11:47:09 SQL> Rem 11:47:09 SQL> Rem DESCRIPTION 11:47:09 SQL> Rem <short description of component this file declares/defines> 11:47:09 SQL> Rem 11:47:09 SQL> Rem NOTES 11:47:09 SQL> Rem <other useful comments, qualifications, etc.> 11:47:09 SQL> Rem 11:47:09 SQL> Rem MODIFIED (MM/DD/YY) 11:47:09 SQL> Rem echong 06/24/99 - rename 11:47:09 SQL> Rem echong 06/05/98 - exceptions table with urowid type 11:47:09 SQL> Rem echong 06/05/98 - Created 11:47:09 SQL> Rem 11:47:09 SQL> 11:47:09 SQL> create table exceptions(row_id urowid, 11:47:09 2 owner varchar2(30), 11:47:09 3 table_name varchar2(30), 11:47:09 4 constraint varchar2(30));Table created.
11:47:09 SQL>
11:47:09 SQL> select * from tab;TNAME TABTYPE CLUSTERID
------------------------------ ------- ---------- DEPT TABLE EMP TABLE BONUS TABLE SALGRADE TABLE ADMIN_EXT_EMPLOYEES TABLE EMPLOYEES TABLE TEST TABLE EMP1 TABLE EXCEPTIONS TABLE9 rows selected.
11:47:18 SQL>
11:48:04 SQL> alter table emp1 11:48:06 2 enable validate constraint pk_emp1 exceptions into exceptions; alter table emp1 * ERROR at line 1: ORA-02437: cannot validate (SCOTT.PK_EMP1) - primary key violated---------把违背约束的记录插入到exceptions 表里
11:48:10 SQL> select * from exceptions;
ROW_ID OWNER TABLE_NAME CONSTRAINT ------------------------------ -------------------- ------------------------------ ------------------------------ AAAM0/AAEAAAAGcAAI SCOTT EMP1 PK_EMP1 AAAM0/AAEAAAAGcAAH SCOTT EMP1 PK_EMP111:48:59 SQL> delete from emp1
11:50:02 2 where rowid in (select row_id from exceptions);2 rows deleted.
11:50:25 SQL> alter table emp1
11:50:29 2 enable validate constraint pk_emp1;Table altered.
11:50:38 SQL>
5、延迟性约束(约束只在提交事务时检查)
11:53:27 SQL> alter table dept1
11:53:38 2 add constraint pk_dept1 primary key (deptno);Table altered.
11:53:58 SQL> alter table emp1
11:54:00 2 add constraint fk_emp1 foreign key(deptno) references dept1(deptno) deferrable;Table altered.
----------deferrable 可延迟 (默认是immediate ,非 deferr 延迟)
11:54:08 SQL> set constraint fk_emp1 deferred;
Constraint set.
---------将约束fk_emp1 进入延迟状态 11:55:04 SQL> select * from emp1;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-DEC-80 800 20 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7566 JONES MANAGER 7839 02-APR-81 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30 7782 CLARK MANAGER 7839 09-JUN-81 2450 10 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30 7876 ADAMS CLERK 7788 23-MAY-87 1100 20 7900 JAMES CLERK 7698 03-DEC-81 950 30 7902 FORD ANALYST 7566 03-DEC-81 3000 20 7934 MILLER CLERK 7782 23-JAN-82 1300 1012 rows selected.
11:55:41 SQL> select * from dept1;
DEPTNO DNAME LOC
---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON11:55:44 SQL> update emp1 set deptno=50 where empno=7900;
1 row updated.
11:56:12 SQL> commit;
commit * ERROR at line 1: ORA-02091: transaction rolled back ORA-02291: integrity constraint (SCOTT.FK_EMP1) violated - parent key not found 11:56:28 SQL> select * from emp1;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-DEC-80 800 20 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7566 JONES MANAGER 7839 02-APR-81 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30 7782 CLARK MANAGER 7839 09-JUN-81 2450 10 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30 7876 ADAMS CLERK 7788 23-MAY-87 1100 20 7900 JAMES CLERK 7698 03-DEC-81 950 30 7902 FORD ANALYST 7566 03-DEC-81 3000 20 7934 MILLER CLERK 7782 23-JAN-82 1300 1012 rows selected.
11:56:39 SQL>
---------插入记录只在提交(commit)时检查