读书频道 > 网站 > 网页设计 > 从零开始学Oracle
5.2.4 检查约束
12-09-27    奋斗的小年轻
收藏    我要投稿   

本文所属图书 > 从零开始学Oracle

本书用简单易懂的实例和大量的图示,深入浅出地介绍了Oracle数据库的操作与编程方面的知识。作者以实际工作为切入点,详细介绍了Oracle数据库的基础知识及PL/SQL程序设计实战的知识。本书共分为17章,主要介绍了...立即去当当网订购

检查约束允许用户在表列中应用一系列的自定义的逻辑,比如工资数必须要大于500,通过指定表达式来检查新插入或更新的字段值,如果布尔表达式结果为False或者是NULL,执行操作的SQL语句将会被回滚,Oracle同时会产生一个异常。一般情况下使用检查约束检查单个字段,有的时候也会使用检查约束验证多个字段。

检查约束既可以在列级别进行定义,也可以在表级别进行定义。与其他对象的定义类似,当在列级别创建检查约束时,只能约束一个字段,而在表级别创建检查约束的话,则可以根据需要同时指定一个或多个字段。

在创建表时,可以直接在字段的后面使用CHECK子句添加检查约束,大多数情况下使用CONSTRAINT为检查约束指定一个友好的名称,CONSTRAINT创建检查约束的语法如下所示:

[CONSTRAINT constraint_name] CHECK (condition)

为了演示检查约束的作用,下面创建了invoice_check表,该表的字段定义级别直接使用CHECK子句定义发票总额和支付总额的检查约束,如下代码所示:

CREATE TABLE invoice_check
(
   invoice_id NUMBER ,
   invoice_total  NUMBER(9,2)  CHECK (invoice_total>0 AND invoice_total<=5000) ,                                                                  
   payment_total NUMBER(9,2)  DEFAULT 0 CHECK(payment_total>0 AND payment_total<=10000)
);

可以看到,创建语句使用CHECK子句为invoice_total的值指定范围为大于0且小于等于5000,payment_total字段的值指定范围为大于0且小于等于10000。当向invoice_check表中插入不符合检查约束条件范围的值时,SQL语句将被回滚并抛出Oracle异常。例如当向invoice_check表中插入不超出检查约束指定范围的值时,会产生如下所示的异常:

INSERT INTO invoice_check VALUES(1,-100,20000);
当执行该语句时,Oracle会提示如下所示的异常:
SQL> INSERT INTO invoice_check VALUES(1,-100,20000);
INSERT INTO invoice_check VALUES(1,-100,20000)
*
第1行出现错误:

ORA-02290: 违反检查约束条件 (SCOTT.SYS_C0011726)

与其他的约束创建相似,在列级别只能对单个字段定义检查约束,为了可以同时对多个字段进行约束,可以在表级别进行创建。为了演示表级别的检查约束创建,下面的代码使用CONSTRAINT关键字同时对invoice_total和payment_total进行了约束,如下代码所示:

CREATE TABLE invoice_check
(
   invoice_id NUMBER ,
   invoice_total  NUMBER(9,2) DEFAULT 0 ,
   payment_total NUMBER(9,2)  DEFAULT 0,
   CONSTRAINT invoice_ck CHECK(invoice_total<=5000 AND payment_total<=10000)
);

可以看到在表级别为约束定义了一个友好的名称。在定义中同时指定了invoice_total和payment_total约束,也就是说只有这两个字段的值都满足条件时才能满足约束条件,才能存储列值,否则当执行类似如下的代码时,会触发异常:

SQL> INSERT INTO invoice_check VALUES(1,6000,100);
INSERT INTO invoice_check VALUES(1,6000,100)
*
第 1 行出现错误:

ORA-02290: 违反检查约束条件 (SCOTT.INVOICE_CK)

在检查约束中还可以使用各种逻辑运算符以及标准的SQL函数来计算布尔值结果,比如可以在检查约束中使用BETWEEN、IN、IS NULL等运算符来组合多种表达式。下面的代码创建了一个名为invoice_check_others的表,在这个表的创建中使用了几种组合的表达式来定义检查约束,如下代码所示:

CREATE TABLE invoice_check_others
(
   invoice_id NUMBER ,
   invoice_name VARCHAR2(20),
   invoice_type INT,
   invoice_clerk VARCHAR2(20),
   invoice_total  NUMBER(9,2) DEFAULT 0 ,
   payment_total NUMBER(9,2)  DEFAULT 0,
   --发票总数必须在1~1000之间
   CONSTRAINT invoice_ck CHECK(invoice_total BETWEEN 1 AND 1000) ,
   --发票名称必须为大写字母
   CONSTRAINT check_invoice_name CHECK (invoice_name = UPPER(invoice_name)),
   --发票类别必须在1~7之间
   CONSTRAINT check_invoice_type CHECK (invoice_type IN (1,2,3,4,5,6,7)),
   --发票处理员工编号不能为NULL值
   CONSTRAINT check_invoice_clerk CHECK (invoice_clerk IS NOT NULL)
);

通过代码可以看到,BETWEEN、IS NOT NULL、UPPER运算符的使用可以加强表达式的表示范围,invoice_check_others表被成功创建后,就可以向该表中使用如下的语句插入记录:

INSERT INTO invoice_check_others VALUES(1,'INVOICE_NAME1',1,'b02393', 1000,1000);

由于上面的INSERT语句的匹配表中创建的检查约束,因此可以看到成功地将记录插入到了数据库中。如果故意违反检查约束,比如将invoice_name改为小写字母的话,SQL*Plus将立即跳出异常代码,如下代码所示:

INSERT INTO invoice_check_others VALUES(1,'invoice_name1',1,'b02393', 1000,1000);
上述代码将触发check_invoice_name的约束违反异常,如下所示:
INSERT INTO invoice_check_others VALUES(1,'invoice_name1',1,'b02393', 1000,1000)
*
ERROR 位于第 1 行:

ORA-02290: 违反检查约束条件 (APPS.CHECK_INVOICE_NAME)

检查约束可以在表中附带简单业务逻辑,这大大方便了应用程序开发人员的编程,但是必须要注意检查约束不是灵丹妙药,而且很多数据库开发人员避免使用检查约束,使用检查约束具有如下的限制:

 不能在视图上定义检查约束,但是可以在视图上使用WITH CHECK OPTION子句,该子句与使用检查约束等同。
 检查约束的表达式中不能包含子查询和标量子查询表达式,不能包含CURRENT_DATE、CURRENT_TIMESTAMP、DBTIMEZONE、LOCALTIMESTAMP、SESSIONTIMEZONE、SYSDATE、SYSTIMESTAMP、UID、USER和USERENV等函数。
 检查约束指定的表达式中不能包含自定义的函数。
 在检查约束的表达式中不能包含伪列,如CURRVAL、NEXTVAL、LEVEL或ROWNUM等伪列。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1.3 功能
下一篇:1.5 小结
相关文章
图文推荐
JavaScript网页动画设
1.9 响应式
1.8 登陆页式
1.7 主题式
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站