oracle实验24:约束

约束

Oracle服务器用约束(constraints) 来防止无效数据输入到表中。约束可以:

–多个表之间的具体关系,比如两个表之间的主外键关系。
–表在插入、更新行或者删除行的时候强制表中的数据遵循约束规则。
–对于成功的操作,约束条件是必须被满足的。
–如果表之间有依赖关系,使用约束可以防止表或表中相关数据的删除。

oracle的五类约束

  • not null非空约束
  • unique唯一约束
  • check检测约束
  • primary key主键约束
  • foreign key外键约束

约束命名

  • 约束命名原则:所有的约束定义存储在数据字典中。
  • 如果给约束一个有意义的名字,约束易于维护,约束命名必须遵守标准的对象命名规则。
  • 如果没有给约束命名,Oracle服务器将用默认格式SYS_Cn产生一个名字,这里n 是一个唯一的整数,来保证名称的唯一性。
  • 建议至少应该给表的主、外键按照命名原则来命名,如可以采用这样的原则来命名,表名_字段名_约束类型。

约束相关的数据字典

  • 约束相关的数据字典USER_CONSTRAINTS和USER_CONS_COLUMNS可以查约束的信息。
  • USER_CONSTRAINTS表:查看表上所有的约束。
  • USER_CONS_COLUMNS表查看与约束相关的列名,该视图对于那些由系统指定名字的约束特别有用。
  • 在约束类型中,C代表CHECK,P代表PRIMARY KEY,R代表FOREIGN KEY,U代表UNIQUE,NOT NULL约束实际上是一个CHECK约束。 
  • 可以使用select constraint_name,constraint_type,table_name,column_name from user_constraints natural join user_cons_columns;语句查询。

约束的语法

CREATE TABLE [schema.] table(column datatype[ DEFAULTexpr][column_constraint],...[table_constraint][,...])

  • 约束可以在两个级别上定义,表级约束与列级约束。
  • 列级约束能够定义完整性约束的任何类型。
  • 表级约束除了NOT NULL之外,能够定义完整性约束的任何类型。

实验24:在表上建立不同类型的约束

􀁺 not null

  • 定义表列后,该列必须有值
  • 可以在建立表的时候说明
  • 可以在表建立后修改
  • 可以给约束指定名称
  • 如果不指定名称,数据库会给一个系统自动指定名称,SYS_C#######
  • user_constraints,user_cons_column可以查约束的信息

建立表的时候指定not null约束,一个系统命名,一个自命名。

SQL>  drop table t1 purge;

表已删除。

SQL> create table t1(name char(9) not null,teleum char(8) constraints t1_tele_n1 not null);

表已创建。

SQL> desc t1
 名称                                         是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 NAME                                       NOT NULL CHAR(9)
 TELEUM                                    NOT NULL CHAR(8)

SQL>  select constraint_name,constraint_type,table_name,column_name from
     user_constraints natural join user_cons_columns;

CONSTRAINT_NAME              C TABLE_NAME        COLUMN_NAME                             
------------------------------ - -----------------------------------------------                                                                                  
PK_DEPT                              P DEPT                   DEPTNO                                                       
FK_DEPTNO                         R EMP                     DEPTNO                                                                                                          
SYS_C004500                      C T1                       NAME                                                                                                          
T1_TELE_N1                        C T1                       TELEUM                            

建立表后指定not null约束

SQL> drop table t1 purge;

表已删除。

SQL> create table t1 as select * from dept;

表已创建。

SQL> desc t1
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 DEPTNO                                             NUMBER(2)
 DNAME                                              VARCHAR2(14)
 LOC                                                  VARCHAR2(13)

使用modify语法,系统命名。

SQL> alter table t1 modify(dname not null);

表已更改。

SQL> desc t1;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 DEPTNO                                             NUMBER(2)
 DNAME                               NOT NULL VARCHAR2(14)
 LOC                                                   VARCHAR2(13)

􀁺 唯一约束UNIQUE

  • 列的值不能重复
  • 可以为null
  • 用索引来维护唯一的
  • 索引的名称和约束的名称相同

建立表时指定UNIQUE约束

SQL> drop table t1 purge;

表已删除。

SQL> create table t1 (name char(9) unique, mail char(8) constraint t1_mail_u unique);

表已创建。

SQL> select constraint_name,constraint_type,table_name,column_name from
     user_constraints natural join user_cons_columns;

CONSTRAINT_NAME              C TABLE_NAME        COLUMN_NAME                      
------------------------------ - -------------------------------------------------            
PK_DEPT                             P DEPT                       DEPTNO                     
PK_EMP                               P EMP                         EMPNO                    
FK_DEPTNO                         R EMP                         DEPTNO                            
SYS_C004503                     U T1                            NAME                 
T1_MAIL_U                          U T1                           MAIL                                                                                                
                                                                           
SQL> desc t1
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 NAME                                               CHAR(9)
 MAIL                                                 CHAR(8)

建立表之后指定UNIQUE约束

SQL> drop table t1 purge;

表已删除。

SQL> create table t1 as select * from dept;

表已创建。

SQL> alter table t1 add constraint u_dname unique (dname);

表已更改。

SQL> select constraint_name,constraint_type,table_name,column_name from
     user_constraints natural join user_cons_columns;

CONSTRAINT_NAME              C TABLE_NAME           COLUMN_NAME                      
------------------------------ - ----------------------------------------------------                
PK_DEPT                             P DEPT                       DEPTNO                                                                                                   
PK_EMP                               P EMP                         EMPNO                                                                              
FK_DEPTNO                         R EMP                        DEPTNO                                                                         
U_DNAME                            U T1                          DNAME                                                                          

SQL> select table_name ,index_name,column_name from user_ind_columns;

TABLE_NAME                  INDEX_NAME                COLUMN_NAME                      
------------------------------ ------------------------------------------------------
DEPT                              PK_DEPT                     DEPTNO                
EMP                                PK_EMP                       EMPNO                    
T1                                  U_DNAME                    DNAME         

􀁺 check约束

  • 定义在字段上的每一记录都要满足的条件
  • 在check中定义检查的条件表达式,数据需要符合设置的条件
  • 条件表达式不允许使用
    • :SYSDATE, UID, USER, USERENV 等函数
    • 参照其他记录的值

建立表时指定check约束

SQL> drop table t1 purge;

表已删除。

SQL>  create table t1(name varchar2(8) check (length(name)>4),mail varchar2(10));

表已创建。

SQL> desc t1
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 NAME                                               VARCHAR2(8)
 MAIL                                                VARCHAR2(10)

建立表之后指定check约束

SQL> alter table t1 add constraint check_mail  check(length(mail)>4) ;

表已更改。

违反约束,会操作失败,给出提示。

SQL> insert into t1 (name,mail) values('asd','zxcvb');
insert into t1 (name,mail) values('asd','zxcvb')
*
第 1 行出现错误:
ORA-02290: 违反检查约束条件 (SCOTT.SYS_C004527)


SQL> insert into t1 (name,mail) values('asdff','asd');
insert into t1 (name,mail) values('asdff','asd')
*
第 1 行出现错误:
ORA-02290: 违反检查约束条件 (SCOTT.CHECK_MAIL)

符合约束条件,操作成功

SQL> insert into t1 (name,mail) values('asdff','asdfg');

已创建 1 行。

􀁺 primary key主键约束

  • 一个表只能有一个主键
  • 主键要求唯一并且非空
  • 可以是联合主键,联合主键每列都要求非空
  • 主键能唯一定位一行,所以主键也叫逻辑rowid
  • 主键不是必需的,可以没有
  • 主键是通过索引实现的
  • 索引的名称和主键的名称相同

建立表的时候指定主键,系统命名

SQL> drop table t1 purge;

表已删除。

SQL> create table t1(mail char(8) primary key, name char(8));

表已创建。

查询用户的约束信息表

SQL> select CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,COLUMN_NAME
    FROM user_constraints natural join user_cons_columns;

CONSTRAINT_NAME             C TABLE_NAME          COLUMN_NAME                                    
----------------------------- - -----------------------------------------
PK_DEPT                            P DEPT                     DEPTNO                                                                 
PK_EMP                              P EMP                       EMPNO                                                     
FK_DEPTNO                        R EMP                      DEPTNO                                  
SYS_C004529                     P T1                        MAIL                                   

查询用户的索引信息表 

SQL> select table_name,index_name,column_name from user_ind_columns;

TABLE_NAME                     INDEX_NAME            COLUMN_NAME                          
--------------------------- -------------------------------------------              
DEPT                                PK_DEPT                    DEPTNO                       
EMP                                  PK_EMP                      EMPNO                        
T1                                    SYS_C004529              MAIL    

表建立后指定自命名主键

SQL> drop table t1 purge;

表已删除。

SQL> create table t1(mail char(8),name char(8));

表已创建。

SQL> alter table t1  add constraint pk_t1_mail primary key(mail);

表已更改。

SQL> select CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,COLUMN_NAME
    FROM user_constraints natural join user_cons_columns;

CONSTRAINT_NAME                C TABLE_NAME           COLUMN_NAME                                    
------------------------------ - -----------------------------------------
PK_DEPT                              P DEPT                 DEPTNO                                                                 
PK_EMP                                P EMP                  EMPNO                                                     
FK_DEPTNO                          R EMP                  DEPTNO                                  
PK_T1_MAIL                         P T1                   MAIL   
                                                                                                                   
SQL> select table_name,index_name,column_name from user_ind_columns;

TABLE_NAME                   INDEX_NAME               COLUMN_NAME                          
--------------------------- ---------------------------------------------              
DEPT                               PK_DEPT                     DEPTNO                       
EMP                                 PK_EMP                       EMPNO                        
T1                                   PK_T1_MAIL                MAIL                         

􀁺 foreign key 外键

  • 指定在表的列上
  • 引用本表其他列,或其他表的其他列
  • 被引用的列有唯一约束或者主键约束
  • 目的是维护数据的完整性
  • 核心是一列是另外一列的自己,null除外

建立主键,建立一个外键来引用主键

SQL> drop table e purge;
drop table e purge
           *
第 1 行出现错误:
ORA-00942: 表或视图不存在

SQL> drop table d purge;
drop table d purge
           *
第 1 行出现错误:
ORA-00942: 表或视图不存在

SQL> create table d as select * FROM dept;

表已创建。

SQL> create table e as select * from emp;

表已创建。

SQL> alter table d add constraint pk_d primary key (deptno);

表已更改。

SQL> alter table e add constraint pk_e foreign key(deptno) references d(deptno);

表已更改。

违反约束
SQL> delete d where deptno=10;
delete d where deptno=10
*
第 1 行出现错误:
ORA-02292: 违反完整约束条件 (SCOTT.PK_E) - 已找到子记录

SQL> update e set deptno=50;
update e set deptno=50
*
第 1 行出现错误:
ORA-02291: 违反完整约束条件 (SCOTT.PK_E) - 未找到父项关键字

SQL> select table_name,index_name,column_name from user_ind_columns;

TABLE_NAME                     INDEX_NAME                COLUMN_NAME                        
---------------------------- ---------------------------------------------------                           
DEPT                                PK_DEPT                   DEPTNO                      
EMP                                  PK_EMP                    EMPNO                   
T1                                    PK_T1_MAIL                MAIL                    
D                                     PK_D                      DEPTNO                        
                                                                                                                                                    

SQL>  select CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,COLUMN_NAME
      FROM user_constraints natural join user_cons_columns;

CONSTRAINT_NAME              C TABLE_NAME        COLUMN_NAME
------------------------------ - --------------------------------------------------                                              
PK_DEPT                              P DEPT                  DEPTNO             
PK_EMP                                P EMP                    EMPNO                                 
FK_DEPTNO                          R EMP                   DEPTNO         
PK_T1_MAIL                         P T1                      MAIL           
PK_D                                   P D                       DEPTNO                                                        
PK_E                                   R E                       DEPTNO                                

已选择6行。

建立被级联的外键

父表的值被删除,子表的相关列自动被赋予null

SQL>  alter table e drop constraint pk_e;

表已更改。

SQL>  alter table e add constraint fk_e foreign key(deptno)
     references d(deptno) on delete set null;

表已更改。

父表的值被删除,子表的相关行自动被删除                                          

SQL> alter table e drop constraint fk_e;

表已更改。

SQL>  alter table e add constraint fk_e foreign key(deptno)
    references d(deptno) on delete cascade;

表已更改。

验证过程及结果

SQL> select * from d;

    DEPTNO DNAME          LOC                                                  
---------- -------------- -------------                                        
        10 ACCOUNTING     NEW YORK                                             
        20 RESEARCH        DALLAS                                               
        30 SALES              CHICAGO                                              
        40 OPERATIONS     BOSTON                                               

SQL> select empno,ename,deptno from e;

     EMPNO ENAME          DEPTNO                                               
---------- ---------- ----------                                               
      7369 SMITH              20                                               
      7499 ALLEN              30                                               
      7521 WARD              30                                               
      7566 JONES              20                                               
      7654 MARTIN            30                                               
      7698 BLAKE              30                                               
      7782 CLARK              10                                               
      7839 KING                10                                               
      7844 TURNER            30                                               
      7900 JAMES              30                                               
      7902 FORD               20                                                             
      7934 MILLER             10                                               

已选择12行。

SQL> delete d where deptno=10;

已删除 1 行。

SQL> select * from d;

    DEPTNO DNAME          LOC                                                  
---------- -------------- -------------                                        
        20 RESEARCH        DALLAS                                               
        30 SALES              CHICAGO                                              
        40 OPERATIONS     BOSTON                                               

SQL> select ename,deptno from e;

ENAME          DEPTNO                                                          
---------- ----------                                                          
SMITH              20                                                          
ALLEN              30                                                          
WARD              30                                                          
JONES              20                                                          
MARTIN            30                                                          
BLAKE              30                                                          
TURNER            30                                                          
JAMES              30                                                          
FORD               20                                                          

已选择9行。

 

增加约束语法:

  • ALTER TABLE table ADD [CONSTRAINT constraint] type (column);

删除约束:

  • Alter table dossier drop constraint dossier_countrycode_fk;
  • Alter table country drop primary key CASCADE;

禁用约束语法:

  • ALTER TABLE table DISABLE CONSTRAINT constraint[CASCADE];

启用约束语法:

  • ALTER TABLE table ENABLE CONSTRAINT constraint;
posted on 2013-06-26 21:10  不吃鱼的小胖猫  阅读(353)  评论(0编辑  收藏  举报