您的位置:首页 > 数据库 > Oracle

Oracle 基础篇 --- 约束

2015-06-29 15:29 585 查看
##第三. 约束

###3.1 创建约束

--创建用户

CREATE TABLE emp1 (
emp1_id NUMBER (6) CONSTRAINT emp1_pk PRIMARY KEY,
first_name VARCHAR2 (20),
last_name VARCHAR2 (25) CONSTRAINT emp1_last_name_nn NOT NULL,
email VARCHAR2 (25)
CONSTRAINT emp1_email_nn NOT NULL CONSTRAINT emp_email_uk UNIQUE,
phone_numbe VARCHAR2 (20),
hire_date DATE CONSTRAINT emp1_hire_date_nn NOT NULL,
job_id VARCHAR2 (10) CONSTRAINT emp1_job_id_nn NOT NULL,
salary NUMBER (8, 2) CONSTRAINT emp1_salary_ck CHECK (salary > 0),
commission_pct NUMBER (2, 2),
manager_id NUMBER (6)
CONSTRAINT emp1_manager_pk REFERENCES employees (employee_id),
department_id NUMBER (4)
CONSTRAINT emp1_dept_fk REFERENCES departments (department_id));

-- 插入合法数据
insert into emp1 values (198, 'Tony', 'Wang','TonyMail',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10);

--插入主键冲突数据
insert into emp1 values (198, 'Tony1', 'Wang1','TonyMail_1',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10);

ERROR at line 1:
ORA-00001: unique constraint (HR.EMP1_PK) violated

--插入email 不唯一的数据
insert into emp1 values (800, 'Tony1', 'Wang1','TonyMail',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10);

ERROR at line 1:
ORA-00001: unique constraint (HR.EMP1_EMAIL_UK) violated

--插入job_id 为空的数据
insert into emp1 values (800, 'Tony1', 'Wang1','TonyMail1',888888,to_date('2011-07-01','YYYY-MM-DD'),'',100000,0.8,100,10);

ERROR at line 1:
ORA-01400: cannot insert NULL into ("HR"."EMP1"."JOB_ID")

-- 插入 salary 为负数
insert into emp1 values (800, 'Tony1', 'Wang1','TonyMail1',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',-100000,0.8,100,10);

ERROR at line 1:
ORA-02290: check constraint (HR.EMP1_SALARY_CK) violated

-- 输入 manager_id 父键不存在
insert into emp1 values (800, 'Tony1', 'Wang1','TonyMail1',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,10,10);

ERROR at line 1:
ORA-02291: integrity constraint (HR.EMP1_MANAGER_PK) violated - parent key not found

###3.2 约束状态



**DISABLE NOVALIDATE:**不检查新数据和现有数据,因此这些数据可能不符合约束条件。当数据来自验证过的源,而且表是只读表时,通常会使用此状态。因此,不会将新数据输入表中。在已清理了数据的数据仓库环境中使用NOVALIDATE。此时不需要进行验证,因而可以节省很多时间。

**DISABLE VALIDATE:**如果约束条件处于此状态,则不允许对有约束条件的列进行任何修改。因为如果在验证现有数据后,又允许将未经检查的数据输入表中,就会出现不一致的情况。通常,在必须验证现有数据但不进行修改时,以及不需要索引来提高性能时,可使用此状态。

**ENABLE NOVALIDATE:**新数据符合约束条件,但现有数据处于未知状态。通常在确信表中只存在纯净数据和符合规则的数据的情况下使用该状态,此时不需要进行验证。但是,不允许将违反规则的新数据输入到系统中。

**ENABLE VALIDATE:**新数据与现有数据均符合约束条件。这是约束条件的典型状态和默认状态。

##1. disable novalidate
SQL> alter table emp1
2  disable novalidate constraint emp1_email_uk;

Table altered.

SQL> insert into emp1 values (199, 'Tony', 'Wang','TonyMail',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10);

1 row created.

SQL> select EMP1_ID, LAST_NAME, EMAIL, SALARY, DEPARTMENT_ID from emp1;

EMP1_ID LAST_NAME  EMAIL          SALARY DEPARTMENT_ID
---------- ---------- ---------- ---------- -------------
198 Wang       TonyMail       100000            10
199 Wang       TonyMail       100000            10

SQL> delete from emp1 where emp1_id = 199;

1 row deleted.

SQL> commit;

##2.disable validate
SQL> alter table emp1
2  disable validate constraint emp1_email_uk;

Table altered.

SQL> insert into emp1 values (199, 'Tony', 'Wang','TonyMail',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10);
insert into emp1 values (199, 'Tony', 'Wang','TonyMail',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10)
*
ERROR at line 1:
ORA-25128: No insert/update/delete on table with constraint (HR.EMP1_EMAIL_UK) disabled and validated

##3.enable novalidate
SQL> alter table emp1
2  enable novalidate constraint emp1_email_uk;

Table altered.

SQL> insert into emp1 values (199, 'Tony', 'Wang','TonyMail',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10);
insert into emp1 values (199, 'Tony', 'Wang','TonyMail',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10)
*
ERROR at line 1:
ORA-00001: unique constraint (HR.EMP1_EMAIL_UK) violated

##4.enable validate
SQL> alter table emp1
2  enable validate constraint emp1_email_uk;

Table altered.

SQL> select owner, constraint_name, constraint_type, table_name, status, validated from user_constraints where table_name = 'EMP1' and constraint_name = 'EMP1_EMAIL_UK';

OWNER      CONSTRAINT_NAME C TABLE_NAME STATUS   VALIDATED
---------- --------------- - ---------- -------- -------------
HR         EMP1_EMAIL_UK   U EMP1       ENABLED  VALIDATED

###3.3 约束条件检查

检查约束条件的时机:

执行语句时(对于非延迟约束条件)

发出COMMIT 时(对于延迟约束条件)

###添加延迟约束
SQL> alter table emp1
2  add score number(2) constraint emp1_score_ck check(score>0) initially deferred deferrable;

Table altered.

###查看约束状态
select constraint_name, constraint_type,status,deferrable,deferred,validated from user_constraints
2  where constraint_name = 'EMP1_SCORE_CK' ;

CONSTRAINT_NAME      CONSTRAINT_TYPE STATUS   DEFERRABLE     DEFERRED  VALIDATED
-------------------- --------------- -------- -------------- --------- -------------
EMP1_SCORE_CK        C               ENABLED  DEFERRABLE     DEFERRED  VALIDATED

###插入小于0的数据
SQL> insert into emp1 values (199, 'Tony1', 'Wang1','TonyMail1',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10,-10);

1 row created.

SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02290: check constraint (HR.EMP1_SCORE_CK) violated

###修改约束为非延迟
SQL> alter table emp1
2  modify constraint emp1_score_ck initially immediate;

Table altered.

select constraint_name, constraint_type,status,deferrable,deferred,validated from user_constraints
2  where constraint_name = 'EMP1_SCORE_CK' ;

CONSTRAINT_NAME      CONSTRAINT_TYPE STATUS   DEFERRABLE     DEFERRED  VALIDATED
-------------------- --------------- -------- -------------- --------- -------------
EMP1_SCORE_CK        C               ENABLED  DEFERRABLE     IMMEDIATE VALIDATED

insert into emp1 values (199, 'Tony1', 'Wang1','TonyMail1',888888,to_date('2011-07-01','YYYY-MM-DD'),'MK_MAN',100000,0.8,100,10,-10)
*
ERROR at line 1:
ORA-02290: check constraint (HR.EMP1_SCORE_CK) violated

#note: You cannot change the state of a NOT DEFERRABLE constraint to INITIALLY DEFERRED.

select constraint_name, constraint_type,status,deferrable,deferred,validated from user_constraints
2   where constraint_name = 'EMP1_SCORE_CK' ;

CONSTRAINT_NAME      CONSTRAINT_TYPE STATUS   DEFERRABLE     DEFERRED  VALIDATED
-------------------- --------------- -------- -------------- --------- -------------
EMP1_SCORE_CK        C               ENABLED  NOT DEFERRABLE IMMEDIATE VALIDATED

SQL> alter table emp1
2  modify constraint emp1_score_ck initially deferred deferrable;
modify constraint emp1_score_ck initially deferred deferrable
*
ERROR at line 2:
ORA-00933: SQL command not properly ended
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息