(一)约束的概念

在Oracle中,可以通过设置约束来防止无效数据进入表中。Oracle一共有5种约束:

  • 主键约束(primary key)
  • 外键约束(foreign key)
  • 唯一性约束(unique)
  • 非空约束(not null)
  • 检查约束(check)

(1)主键约束

--主键约束可以定义在一列或多列上,值具有唯一性、非空性;

--在一个表上只能定义一个主键约束;

--Oracle会自定在主键约束的列上创建唯一性索引,可以指定唯一性索引的位置及存储参数。

(2)外键约束

--外键约束列的取值来源于参照表(父表)的参照列的值,或者空值;

--定义外键约束的列只能参照父表的主键约束列和唯一性约束列;

--父表与子表必须在同一个数据库中。

(3)唯一性约束

--可定义在一列或多列上,列的取值必须唯一;

--如果在某些列上定义了唯一性约束,而没有定义非空约束,那么在这些列上可以出现多个空值;

--Oracle会自定在主键约束的列上创建唯一性索引,可以指定唯一性索引的位置及存储参数。

(4)非空约束

--只能定义在列上;

--在同一个表中可定义多个非空约束。

(5)检查约束

--检查约束用来限制列的取值范围,其表达式必须引用相应列,表达式的计算结果是一个布尔值;

--一个列可以定义多个检查约束

(二)列级约束与表级约束

列级约束是对某一个特定列的约束,包含在列的定义中,直接跟在其它定义之后,不需要指出列名。其语法为:

  1. column_definition [CONSTRAINT constraint_name] constraint_type ...

表级约束的定义与列的定义相互独立,通常用于多列组合的约束,定义表级约束要指出约束的名称。其语法为:

  1. [CONSTRAINT constraint_name]
  2. constraint_type(column1,[column2...]);

需要注意的是,除了非空约束只能定义列级约束外,其他的均可定义列级/表级约束。

(三)约束的状态

根据在数据插入、更新时是否对数据进行约束检查,约束状态分为激活状态(ENABLE)和禁用状态(DISABLE);

根据是否对表中已有数据进行约束检查,约束状态分为验证状态(VALIDATE)和非验证状态(NOVALIDATE);

组合之后,一共有四种约束状态:

约束状态

定义

特点

激活验证状态
(ENABLE VALIDATE)
激活约束且约束检查已有数据 对表中已有数据进行检查,对后续插入、更新的数据也会进行检查
激活非验证状态
(ENABLE NOVALIDATE)
激活约束但是不检查表中已存在的数据 不检查目前表中已经存在的数据,但会检查后续插入、更新的数据
禁用验证状态
(DISABLE VALIDATE)
不激活约束但是会去检查表中已经存在的数据 Oracle不允许进行任何DML(insert/update/delete)操作,因为操作无法得到约束的检查。表处于只读模式
禁用非验证状态
(DISABLE NOVALIDATE)
不激活验证且不检查表中已有的数据 不会对表中数据进行约束检查,也不会对新插入的数据进行约束检查

(四)创建约束

(1)创建列级约束

创建列级约束的语法为:

  1. INITIALLYCONSTRAINT constraint_name --约束名
  2. [ --选择5中约束类型
  3. [NOT] NULL |
  4. [UNIQUE] |
  5. [PRIMARY KEY] |
  6. [CHECK (condition)] |
  7. [REFERENCES [schema.]object[(column)] [ON DELETE CASCADE | SET NULL]]
  8. ]
  9. [ --是否延迟约束检查
  10. [NOT DEFERRABLE] |
  11. [DEFERRABLE [INITIALLY IMMEDIATE | DEFERRED]]
  12. ]
  13. [ENABLE | DISABLE] --定义约束检查的类型
  14. [VALIDATE | NOVALIDATE ]
  15. [USING INDEX index_clause] --约束上索引的定义(主键约束与唯一性约束)
  16. [EXCEPTIONS INTO [schema.]table] --违反约束的数据的存储方式

参数说明:

--cinstraint_name:约束名,如果没有为约束命名,oracle将自动为约束命名,命名样式为SYS_Cn,n是数据库对象的唯一编号;

--ON DELETE CASCADE:定义级联删除的外键约束;

--ON DELETE SET NULL:定义置空删除的晚间约束;

--NOT DEFERRABLE:约束不可延迟;

--DEFERRABLE:约束可以延迟;

--INITIALLY IMMEDIATE:可延迟约束的立即检查;

--DEFERRED:可延迟约束的延迟检查;

--USING INDEX index_clause:创建 唯一性索引的参数设置(存在与主键约束、唯一性约束);

--EXCEPTIONS INTO:将违反约束的记录保存到表中。

(2)定义表级约束

列级约束是定义在列上的,如果需要在多个列上定义约束,则需采用表级约束,表级约束语法如下:

  1. .INITIALLYCONSTRAINT constraint_name --约束名
  2. [ --选择4种约束类型,非空约束只能定义在列上
  3. [UNIQUE(column1[,column2…])] |
  4. [PRIMARY KEY(column1[,column2…])] |
  5. [CHECK (condition)] |
  6. [FOREIGN KEY (column1[,column2…]) --外键约束需要指出要约束的列,与列级约束有较大区别
  1. REFERENCES [schema.]object[(column1[,column2…])] [ON DELETE CASCADE | SET NULL]]
  2. ]
  3. [ --是否延迟约束检查
  4. [NOT DEFERRABLE] |
  5. [DEFERRABLE [INITIALLY IMMEDIATE | DEFERRED]]
  6. ]
  7. [ENABLE | DISABLE] --定义约束检查的类型
  8. [VALIDATE | NOVALIDATE ]
  9. [USING INDEX index_clause] --约束上索引的定义(主键约束与唯一性约束)
  10. [EXCEPTIONS INTO [schema.]table] --违反约束的数据的存储方式

(五)添加、修改、重命名、删除约束

(1)添加约束

语法为:

  1. ALTER TABLE table_name
  2. ADD [CONSTRAINT constraint_name] constraint_type(column1[,column2...])
  3. [constraint_parameters];

例子1.添加约束

  1. --创建表books
  2. create table books
  3. (
  4. id number(6),
  5. title varchar2(20),
  6. isbn number(20),
  7. auther varchar(10),
  8. price number(6,2),
  9. discribe varchar2(1000),
  10. pid number
  11. );
  12. Table created
  13.  
  14. --创建表publish(用来辅助books创建外键约束)
  15. create table publish
  16. (
  17. pid number primary key,
  18. name varchar2(20)
  19. );
  20. Table created
  21.  
  22. --添加主键约束
  23. SQL> alter table books add constraint books_pk primary key (id);
  24.  
  25. Table altered
  26.  
  27. --添加外键约束
  28. --需要注意,参照的父表的列需要是主键约束列或唯一性约束列
  1. --主要注意,外键约束的references带‘s
  2. SQL> alter table books add constraint books_fk foreign key (pid) references publish(pid);
  3.  
  4. Table altered
  5.  
  6. --创建唯一性约束
  7. SQL> alter table books add constraint books_unique unique (title);
  8.  
  9. Table altered
  10.  
  11. --创建检查约束
  12. SQL> alter table books add constraint books_check check (price > 0);
  13.  
  14. Table altered
  15.  
  16. --需要特别注意,非空约束只能使用modify来创建/删除 ,不能使用add方式
  17. --1.创建非空约束
  18. SQL> alter table books modify auther not null;
  19.  
  20. Table altered
  21. --2.删除非空约束
  22. SQL> alter table books modify auther null;
  23.  
  24. Table altered

(2)修改约束

可以使用ALTER TABLE … MODIFY修改约束参数,语法为:

  1. ALTER TABLE table_name
  2. MODIFY [CONSTRAINT constraint_name] |
  3. [PRIMARY KEY] | [UNIQUE(column1[,column2,...])] --主键约束和唯一性约束可以通过约束类型来修改
  4. [constraint_parameters]

例子2.修改约束

  1. --修改检查约束,将其置为不检查表中已有数据
  2. SQL> alter table books modify constraint books_check novalidate;
  3.  
  4. Table altered
  5.  
  6. --使主键约束不可用
  7. SQL> alter table books modify primary key disable;
  8.  
  9. Table altered

(3)重命名约束

可以使用ALTER TABLE … RENAME…来重命名约束,语法为:

  1. ALTER TABLE table_name RENAME CONSTRAINT old_constrain_name TO new_constraint_name;

(4)删除约束

可以使用ALTER TABLE … DROP …来删除约束,语法为:

  1. ALTER TABLE table_name
  2. DROP [CONSTRAINT constraint_name] |
  3. [PRIMARY KEY] | [UNIQUE (column1 [,column2,...])]
  4. [CASCADE] [KEEP | DROP INDEX]

对于删除约束,需要注意:

1.可以通过约束名称来删除约束,对于主键约束和唯一性约束,也可以指定约束的类型来删除约束;

2.如果要删除的主键约束或唯一性约束已经被子表中的外键约束引用,需要加CASCADE关键字,删除子表中的外键约束;

3.在删除主键约束/唯一性约束时,如果要保留主键约束/唯一性约束创建时生成的唯一性索引,则需要使用KEEP关键字。

图、books与publish的关系

例子3.删除主键约束

  1. --根据上图,我们发现books的外键引用了publish的主键,如果直接删除,会报错,只有加了cascade后才能删除主键约束
  1. --删除主键约束后才去看books表,对应的外键约束也被删除了
  1. SQL> alter table publish drop primary key;
  2.  
  3. alter table publish drop primary key
  4.  
  5. ORA-02273: 此唯一/主键已被某些外键引用
  6.  
  7. SQL> alter table publish drop primary key cascade;
  8.  
  9. Table altered

(六)关于外键约束的数据删除方式

假如两个表之间存在外键约束的关系,在父表进行数据删除时,子表的关联数据如何处理?Oracle提供了3种方式。

(1)受限删除【默认】,如果子表中有与父表关联的记录存在,则不能删除数据;

例子4.受限删除无法删除已经关联的数据

  1. create table table_a --父表
  2. (
  3. id number primary key,
  4. name varchar(20)
  5. );
  6.  
  7. create table table_b1 --子表
  8. (
  9. id number references table_a(id), --默认是受限删除
  10. country varchar2(30)
  11. )
  12.  
  13. SQL> insert into table_a values(1,'lijiaman');
  14.  
  15. 1 row inserted
  16.  
  17. SQL> insert into table_b1 values(1,'test');
  18.  
  19. 1 row inserted
  20.  
  21. SQL> commit;
  22.  
  23. Commit complete
  24.  
  25. SQL> delete table_a where id = 1; --子表有关联数据,导致父表数据也无法删除
  26.  
  27. delete table_a where id = 1
  28.  
  29. ORA-02292: 违反完整约束条件 (LIJIAMAN.SYS_C0013519) - 已找到子记录
  30.  
  31. SQL> insert into table_a values(2,'fg');
  32.  
  33. 1 row inserted
  34.  
  35. SQL> delete table_a where id = 2; --子表无关联数据,父表数据可以删除
  36.  
  37. 1 row deleted
  38.  
  39. SQL> commmit;

(2)级联删除,删除父表数据的同时也会将外键关联的子表的记录删除;

例子5.级联删除外键约束会删除子表关联数据

  1. SQL> drop table table_b1; --删除table_b1
  2.  
  3. Table dropped
  4.  
  5. create table table_b2 --子表
  6. (
  7. id number references table_a(id) on delete cascade, --级联删除外键约束
  8. country varchar2(30)
  9. );
  10. SQL> insert into table_b2 values(1,'ch');
  11.  
  12. 1 row inserted
  13.  
  14. SQL> select * from table_a ; --两个表各有1行关联数据
  15.  
  16. ID NAME
  17. ---------- --------------------
  18. 1 lijiaman
  19.  
  20. SQL> select * from table_b2;
  21.  
  22. ID COUNTRY
  23. ---------- ------------------------------
  24. 1 ch
  25.  
  26. SQL> delete table_a where id = 1; --删除父表数据,子表关联数据也随之删除
  27.  
  28. 1 row deleted
  29.  
  30. SQL> commit;
  31.  
  32. Commit complete
  33.  
  34. SQL> select * from table_a;
  35.  
  36. ID NAME
  37. ---------- --------------------
  38.  
  39. SQL> select * from table_b2;
  40.  
  41. ID COUNTRY
  42. ---------- ------------------------------

(3)置空删除,父表数据删除后,子表中关联记录的外键约束的列值置为空;

例子6.置空删除外键约束会将子表关联记录的外键列置为空值

  1. create table table_b3 --子表
  2. (
  3. id number references table_a(id) on delete set null, --置空删除外键约束
  4. country varchar2(30)
  5. );
  6.  
  7. SQL> insert into table_a values(1,'adrci'); --往两个表插入1行关联数据
  8.  
  9. 1 row inserted
  10.  
  11. SQL> insert into table_b3 values(1,'srvctl');
  12.  
  13. 1 row inserted
  14.  
  15. SQL> commit;
  16.  
  17. Commit complete
  18.  
  19. SQL> select * from table_a;
  20.  
  21. ID NAME
  22. ---------- --------------------
  23. 1 adrci
  24.  
  25. SQL> select * from table_b3;
  26.  
  27. ID COUNTRY
  28. ---------- ------------------------------
  29. 1 srvctl
  30.  
  31. SQL> delete table_a where id = 1; --删除id=1的数据,父表整条记录被删除,子表仅置空了关联数据的外键列值
  32.  
  33. 1 row deleted
  34.  
  35. SQL> select * from table_a;
  36.  
  37. ID NAME
  38. ---------- --------------------
  39.  
  40. SQL> select * from table_b3;
  41.  
  42. ID COUNTRY
  43. ---------- ------------------------------
  44. srvctl

(七)与约束相关的数据字典

视图名称 说明
DBA_CONSTRAINTS
ALL_CONSTRAINTS
USER_CONSTRAINTS
包含数据库中所有约束的定义信息;
包含当前用户可以看到的所有约束的定义信息;
包含当前用户拥有的约束的定义信息;
DBA_CONS_COLUMNS
ALL_CONS_COLUMNS
USER_CONS_COLUMNS
记录了约束列信息,DBA_ 、ALL_ 、USER_的用法与前面相同

[Oracle]约束(constraint)的更多相关文章

  1. Oracle约束(Constraint)详解

    概述 约束是数据库用来确保数据满足业务规则的手段,不过在真正的企业开发中,除了主键约束这类具有强需求的约束,像外键约束,检查约束更多时候仅仅出现在数据库设计阶段,真实环境却很少应用,更多是放到程序逻辑 ...

  2. Oracle 约束类型

    在Oracle中的约束类型:NOT NULLUNIQUE KeyPRIMARY KEYFOREIGN KEYCHECK create table emp--创建表格 ,注意约束( empno numb ...

  3. ORACLE中CONSTRAINT的四对属性

    ORACLE中CONSTRAINT的四对属性 summary:在data migrate时,某些表的约束总是困扰着我们,让我们的migratet举步维艰,怎样利用约束本身的属性来处理这些问题呢?本文具 ...

  4. Oracle约束操作

    约束的概念: 约束是在表中定义的用于维护数据库完整性的一些规则.通过为表中的字段定义约 束,可以防止将错误的数据插入到表中. 注意: 1.如果某个约束只作用于单独的字段,既可以在字段级定义约束,也可以 ...

  5. SQL基础--> 约束(CONSTRAINT)

    --============================= --SQL基础--> 约束(CONSTRAINT) --============================= 一.几类数据完 ...

  6. ORACLE约束总结

    你对ORACLE约束的了解如何?比较模糊还是相当透彻?如果你对下面几个问题了如指掌的话,恭喜你,你已经对约束掌握得比较好了,不用看这篇文章了.ORACLE的约束有啥功能作用? 有哪些类型约束(不同版本 ...

  7. SQL Server - 约束 CONSTRAINT

    总结 约束放置在表中,以下五种约束: NOT NULL 非空约束C 指定的列不允许为空值 UNIQUE 唯一约束U 指定的列中没有重复值,或该表中每一个值或者每一组值都将是唯一的 PRIMARY KE ...

  8. 【Oracle】Oracle约束的总结

    你对ORACLE约束的了解如何?比较模糊还是相当透彻?如果你对下面几个问题了如指掌的话,恭喜你,你已经对约束掌握得比较好了,不用看这篇文章了.ORACLE的约束有啥功能作用? 有哪些类型约束(不同版本 ...

  9. Oracle——约束

    NOT NULLUNIQUE PRIMARY KEYFOREIGN KEYCHECK 如果不指定约束名 ,Oracle server 自动按照 SYS_Cn 的格式指定约束名 --指定约束名 CREA ...

  10. oracle约束约束状态和设计习惯

    oracle约束状态有几个项目,会让人迷惑,分别是: enable/disable--是否启用/禁用 validate/invalidate--确认/不确认 deferrable/not deferr ...

随机推荐

  1. JAVAEE学习——struts2_02:结果跳转方式、访问servletAPI方式、获得参数以及封装和练习:添加客户

    一.结果跳转方式 <action name="Demo1Action" class="cn.itheima.a_result.Demo1Action" m ...

  2. [Leetcode] Binary search--275 H-Index

    Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimize ...

  3. 两个HTML,CSS布局实例

    今天首先仿照某公司页面只做了一个几乎一模一样,连距离都相同的页面. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional/ ...

  4. Vue.js组件之间的通信

    导语:组件之间的关系不外乎两种, 父子组件和非父子组件,本文将对两类组件之间的通信方式进行详细阐述. 父子组件间的通信 通信方式1(单向绑定): Props down, Events up (建议使用 ...

  5. angularjs下拉框空白

    搜索angularjs下拉框空白,可以出现很多解决方案,但是对于静态字段来说,网上目前还没有找到解决方案,如下: <select class="form-control" n ...

  6. AngularJS高级程序设计读书笔记 -- 指令篇 之 内置指令

    1. 内置指令(10-12 章) AngularJS 内置超过 50 个内置指令, 包括 数据绑定,表单验证,模板生成,时间处理 和 HTML 操作. 指令暴露了 AngularJS 的核心功能, 如 ...

  7. position定位和添加阴影

    定位:style="position: absolute; bottom: 0; width: 100%;background: rgb(255, 255, 255);padding-bot ...

  8. CSS技巧和经验列表

    如何清除图片下方出现几像素的空白间隙? img{display:block;} 如何让文本垂直对齐文本输入框? input{vertical-align:middle;} 如何使文本溢出边界显示为省略 ...

  9. 关于MATLAB处理大数据坐标文件201762

    经过头脑风暴法想出了很多特征,目前经过筛选已经提交了两次数据,数据提交结果不尽如人意,但是收获很大. 接下来继续提取特征,特征数达到27时筛选出20条特征,并找出最佳搭配

  10. Web 前端代码规范

    Web 前端代码规范 最后更新时间:2017-06-25 原始文章链接:https://github.com/bxm0927/web-code-standards 此项目用于记录规范的.高可维护性的前 ...