回 帖 发 新 帖 刷新版面

主题:Oracle PL/SQL从入门到精通

Oracle PL/SQL从入门到精通

丁士锋  等编著













清 华 大 学 出 版 社
北  京
内 容 简 介
本书以面向应用为原则,深入浅出地介绍了Oracle平台上使用PL/SQL语言进行数据库开发的技术。通过大量的示例,详细介绍了PL/SQL的语言特性、使用技巧,同时配以两个在实际工作中的案例深入地剖析了使用PL/SQL进行Oracle开发的方方面面。
本书附带1张DVD光盘,内容为作者为本书录制的全程语音教学视频及本书所涉及的源代码。
本书分为5大篇共20章。涵盖的内容主要有PL/SQL语言基础、开发环境、变量与类型、控制语句、数据表的管理和查询、数据表的操纵、使用PL/SQL的记录与集合、各种内置函数、游标、事务处理、异常处理、子程序、包、面向对象的开发等技术点。通过示例性的代码,由浅入深,详细介绍了每一个技术要点在实际工作中的应用,对各种技术要点的应用场合进行了细致的分析。
本书适合于使用PL/SQL进行应用程序开发的人员、对软件开发有兴趣的学生及爱好者阅读和参考;对数据库管理员、企业IT运维人员也具有很强的指导作用。


本书封面贴有清华大学出版社防伪标签,无标签者不得销售。
版权所有,侵权必究。侵权举报电话:010-62782989  13701121933

图书在版编目(CIP)数据

Oracle PL/SQL从入门到精通 / 丁士锋等编著. —北京:清华大学出版社,2012.6
ISBN 978-7-302-28103-0

Ⅰ. ①O…  Ⅱ. ①丁…  Ⅲ. ①关系数据库-数据库管理系统,Oracle  Ⅳ. ①TP311.138

中国版本图书馆CIP数据核字(2012)第030492号


责任编辑:夏兆彦
封面设计:
责任校对:徐俊伟
责任印制:

出版发行:清华大学出版社    
网    址:http://www.tup.com.cn, http://www.wqbook.com
地    址:北京清华大学学研大厦A座        邮    编:100084
社 总 机:010-62770175                邮    购:010-62786544
投稿与读者服务:010-62776969,c-service@tup.tsinghua.edu.cn
质量反馈:010-62772015,zhiliang@tup.tsinghua.edu.cn
印 刷 者:
装 订 者:肖  米
经    销:全国新华书店
开    本:185mm×260mm     印    张:42.25       字    数:1055千字
          (附DVD 1张)
版    次:2012年6月第1版                  印    次:2012年6月第1次印刷
印    数:1~5000
定    价:25.00元
产品编号:045147-01
[b]当当地址:http://searchb.dangdang.com/?key=%20%20%20Oracle%20PL[/b]

回复列表 (共54个回复)

21 楼


为了演示外键约束的实际效果,下面向vendors表中插入两条记录,插入语句如下所示。

INSERT INTO vendors VALUES(1,'纵横国际');
INSERT INTO vendors VALUES(2,'宇河国际');

接下来向invoice表中使用INSERT语句插入两条记录:

INSERT INTO invoice(invoice_id,vendor_id,invoice_number) VALUES(1,1,
'0001');                                --插入成功
INSERT INTO invoice(invoice_id,vendor_id,invoice_number) VALUES(1,3,
'0001');                                --插入失败

因为invoice表中的vendor_id字段具有一个外键约束,关联到vendors表的主键vendor_id列,因此第2条语句向invoice表中插入一条在vendors表中不存在的vendor_id字段值时,Oracle提示插入失败,在Toad中将弹出如图5.8所示的错误提示

[img]http://www.tu265.com/di-9be9981115a64a69d607582471353a87.png[/img]

22 楼

再来看看级联删除。在代码5.8中,已经为vendor_id外键设置了级联删除特性,因此当从vendors表中删除记录时,与该vendor_id相关的invoice表中的相关记录也会被删除,例如执行如下的代码删除vendors表中vendor_id为1的供应商id号:

DELETE FROM vendors WHERE vendor_id = 1;

现在来查询invoice表,看看相关的记录是否发生了变化,执行如下的查询代码:

SELECT * FROM invoice;

执行结果如下所示。

SQL> SELECT invoice_id,vendor_id,invoice_number FROM invoice;
    INVOICE_ID          VENDOR_ID       INVOICE_NUMBER
------------------ ------------ ----------------------
           1                   2                  0001

可以看到,vendor_id为1的记录果然已经被级联删除。

23 楼

5.2.3  创建检查约束
检查约束允许指定一个布尔表达式,在记录值被存储到列中前进行检查以便仅存储满足条件的记录值,如果布尔表达式结果为False或NULL,那么相关的SQL语句将产生一个异常,检查约束通常用于单列校验,或者是同一行的多个列的数据验证。
与其他的列类型相似,检查约束既可以在列级别进行定义,也可以在表级别进行定义。应用在列级别的检查约束一次只能约束一个字段,但是表级别的检查约束可以根据需要同时应用一个或多个字段。
检查约束的声明语法如下所示。

[CONSTRAINT constraint_name] CHECK (condition)

方括号中的为可选项,如果在列级别中定义检查约束,可以省略CONSTRAINT关键字,例如下面的示例代码创建了一个名为invoices_check的表,在列级别使用CHECK关键字分别定义了两个约束,如代码5.10所示。
代码5.10  列级别的检查约束
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)
);

上述代码在列级别指定invoice_total的值大于0且小于等于5000,payment_total的值大于0小于等于10000,因此向invoice_check表中插入不符合条件的值时,将会触发异常。例如下面的代码向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进行了约束,如代码5.11所示。
代码5.11  表级别的检查约束
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)
);

在表级别使用CONSTRAINT关键字,可以为约束定义一个具有良好意义的名称。在示例中同时指定了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的表,使用了各种运算符创建检查约束,如代码5.12所示。
代码5.12  在约束中使用函数和布尔运算符
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,2,3,4,5,6,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等函数来创建检查约束。在创建了上述的表之后,下面的语句向表中插入一条记录:

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

上述INSERT语句的所有条件都匹配表中创建的约束,如果将invoice_name改为小写字母,将引发约束违反异常,如下代码所示。

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)

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

24 楼

5.2.4  查看表约束
Oracle将用户创建的表、约束等信息都放在数据字典表中,允许开发人员查询数据字典表或视图来获取数据库对象的信息,比如一个表的创建者信息、创建时间信息、所属表空间信息、用户访问权限信息等。如果用户在对数据库中的数据进行操作时遇到困难,就可以访问数据字典来查看数据库对象的详细信息,数据字典中包含的主要内容如下所示。
&#61553;    各种方案对象的定义信息,如表、视图、索引、同义词、存储过程、函数、包、触发器和各种对象。
&#61553;    存储空间的分配信息,如为某个对象分配了多少存储空间,该对象使用了多少存储空间。
&#61553;    安全信息,如账户、权限、角色、完整性约束信息。
&#61553;    数据库实例运行时的性能和统计信息。
&#61553;    其他数据库运行过程中的基本信息。
&#61477;注意:数字字典表本身不能被直接访问,必须通过数据字典视图来访问数据字典中的信息,系统的数据字典视图以V$开头。
数据字典表根据其前缀又可分为如下4类。
&#61553;    user:用户所创建对象对应的数据字典表,例如user_objects、user_tables等。
&#61553;    all:用户所能访问对象(包括用户创建的对象)对应的数据字典表,例如all_objects、all_tables等。
&#61553;    dba:所有对象对应的数据字典表,例如all_objects、all_tables等。
&#61553;    v$:描述系统性能相关的数据字典表。如通过v$version表可获得数据库版本信息。
有两个数据字典视图提供了约束的详细信息。
&#61553;    user_constraints:对于表中的每一个约束,在该表中都有一条记录描述这个约束,该表包含约束应用到的表,如果知道约束名,想知道约束类型,可以查询user_constraints,这个视图描述了约束的定义,但是它不提供约束定义在哪些字段名称上。
&#61553;    user_cons_columns:视图中显示约束的字段名称。如果主键是一个联合(多字段)主键,这个视图中将有这个约束的两条记录,联合主键的每一个字段对应一条记录,每一条记录通过position(在联合主键中的位置)来区别。
例如要查询invoice_check_others表中的所有约束信息,可以使用如下的SQL语句:

SELECT constraint_name, search_condition, status
  FROM user_constraints
 WHERE table_name = UPPER ('invoice_check_others');

在Toad中,该语句的执行结果如图5.9所示。

25 楼



[img]http://www.tu265.com/di-06997abed252003e260ae191040d222d.png[/img]

26 楼


在user_constraints视图中并没有包含约束应用到的列信息,为了获取invoice_check_单位others表的列约束信息,可以使用如下的代码查询user_cons_columns视图,如以下代码所示。

--查询约束应用的列信息 
SELECT constraint_name, column_name
  FROM user_cons_columns
 WHERE table_name = UPPER ('invoice_check_others');

上述代码在Toad中的执行结果如代码5.10所示。

[img]http://www.tu265.com/di-be66035a5a2f11e641a686bb833a92e3.png[/img]

27 楼

作为DBA,可以使用all_constraints和all_cons_columns来获取约束的详细信息。下面的查询使用Oracle连接查询这两个表来获取约束的详细信息,如代码5.13所示。
代码5.13  使用连接查询获取约束详细信息
SELECT a.table_name, a.constraint_name, a.search_condition, b.column_name,
       a.constraint_type
  FROM all_constraints a, all_cons_columns b
 WHERE a.table_name = UPPER ('invoice_check_others')
   AND a.table_name = b.table_name
   AND a.owner = b.owner
   AND a.constraint_name = b.constraint_name;

上述语句的输出结果如图5.11所示。

[img]http://www.tu265.com/di-0f31509a9cec93dedb76bd737ad4da1a.png[/img]

28 楼

Toad提供的表信息向导中的Constraints标签页中,以图形化的方式显示了当前表中所有创建的约束及约束的定义文本,这使得用户可以更方便地查看表的约束信息,如图5.12所示。
通过使用该窗口的工具栏,可以在可视化的工具中创建约束。对于不太熟悉SQL语句或希望快速创建约束的用户来说,提供了简单易用的方式。例如当单击工具栏的 按钮后,将显示如图5.13所示的创建约束窗口。


[img]http://www.tu265.com/di-0f31509a9cec93dedb76bd737ad4da1a.png[/img]
通过该窗口可以看到Oracle约束的众多选项与设置方式,在设置了约束后,可以通过SQL标签页来查看产生的SQL语句代码,这也是学习Oracle语法的一种好方法。

29 楼

5.3  修  改  表
当表成功创建后,在程序的开发过程中可能需要对表的结构进行更改,比如添加、修改或删除列、约束等,更改列字段类型、字段大小等操作,可以使用ALTER TABLE语句来完成。
5.3.1  修改表列
使用ALTER TABLE语句修改表列可以做如下4件事情。
&#61553;    向表中添加新的列。
&#61553;    修改已经存在的列的类型或数据范围。
&#61553;    删除已经存在的列。
&#61553;    重命名表列。
ALTER TABLE语句用来修改表列的语法如下所示。

ALTER TABLE [schema_name.]table_name
{
  ADD column_name data_type [column_attributes] |
  DROP COLUMN column_name |
  MODIFY column_name data_type [column_attributes]
}

下面分别介绍如何进行表列的新增、修改与删除。
1.新增表列
在代码5.11中创建了invoice_check表,这个表包含invoice_id、invoice_total、payment_total这3个字段。现在需要向该表中插入一个invoice_name字段,用来描述发票名称,具有20个字符宽度,可以使用如下的ALTER TABLE语句:

ALTER TABLE invoice_check ADD invoice_name VARCHAR2(20);

这条语句会将invoice_name添加到invoice_check的最右边。由声明语法可知,在添加列时还可以定义列属性,比如指定NOT NULL、UNIQUE或CHECK约束。例如下面的代码在添加了invoice_name列时同时指定了约束信息。

ALTER TABLE invoice_check ADD invoice_name VARCHAR2(20) CHECK
(LENGTH(invoice_name)<=8);

上述代码指定invoice_name的长度不能大于8个字符,现在可以查询invoice_check表,可以看到新创建的invoice_name位于最右边,初始值为NULL,如下所示。

INVOICE_ID     INVOICE_TOTAL    PAYMENT_TOTAL     INVOICE_NAME
------------ --------------- ----------------- ---------------
           1          200              200
          21          300              400
2.修改表列
使用ALTER TABLE可以对现有表已经存在的列进行修改,但是这个功能应该小心使用,Oracle并不允许可能会导致数据丢失的任何更改。
&#61477;注意:更改数据表列是一件具有危险性的行为,应该在DBA的许可之下,在测试环境中测试好后才能在生产环境中更改。
下面更改invoice_check表中的invoice_name列,设置其宽度为100个字符,ALTER TABLE语句如下所示。

--移除现有的约束
ALTER TABLE invoice_check DROP CONSTRAINT SYS_C001118879;
--修改列字段的长度,并重新创建约束
ALTER TABLE invoice_check MODIFY invoice_name VARCHAR2(100) CHECK(LENGTH
(invoice_name)<=50);

上面的代码首先清除了invoice_name原有的约束SYS_C001118879,当然这个编号在读者的系统上可能不同,在不指定约束名时由Oracle根据序列号机制创建约束名称。在MODIFY语句中指定invoice_name的长度为100个字符,语句后面的CHECK将会创建一条新的约束,使得字符串长度可以小于50个字符。
下面向invoice_check表插入一条新的记录,该记录中指定了invoice_name字段的值,如以下代码所示。

INSERT INTO invoice_check
     VALUES (3, 300, 400, 'This is a invoice_name field');

现在查询invoice_check表,可以看到如下所示的结果:

SQL> set linesize 300
SQL> select * from invoice_check;
INVOICE_ID  INVOICE_TOTAL  PAYMENT_TOTAL    INVOICE_NAME
----------- ------------- -------------- ----------------------------
         1           200           200
        21           300           400
         3           300           400          This is a invoice_name field

Oracle数据库不允许会引起数据库数据丢失的列更改,因此现在如果将invoice_name的长度变回为20,将会引起异常,如下所示。

SQL> ALTER TABLE invoice_check MODIFY invoice_name VARCHAR2(20); 
ALTER TABLE invoice_check MODIFY invoice_name VARCHAR2(20)
                                 *
ERROR 位于第 1 行:
ORA-01441: 无法减小列长度,因为一些值过大
3.删除表列
使用ALTER TABLE的DROP COLUMN语法可以将一个已存在的列删除。下面的代码将删除invoice_check表的invoice_name列:

ALTER TABLE invoice_check DROP COLUMN invoice_name;

上面的代码将删除invoice_check表中的invoice_name字段,无论字段中是否有值。
4.重命名表列
使用ALTER TABLE语句,可以对现有的数据表的表列重新命名,例如要重命名invoice_check表的invoice_name字段名为invoice_name_short,可以使用如下的语法:

ALTER TABLE invoice_check RENAME COLUMN invoice_name TO invoice_name_short;

通过RENAME COLUMN关键字,可以将一个表字段名称重命名为指定的目标字段名称。现在查询invoice_check表,可以看到字段名称果然已经被更改,如下所示。

SQL> col INVOICE_NAME_SHORT FORMAT A30;
SQL> select * from invoice_check;
INVOICE_ID   INVOICE_TOTAL   PAYMENT_TOTAL   INVOICE_NAME_SHORT
----------- -------------- --------------- -------------------
         1           200              200          Demo1
         2           300              400          Demo2
         3           300              400          This is a invoice_name field
         3           300              400          This is a invoice_name field
         4           300              400          Demo2

代码中使用col指定了invoice_name_short列的字段宽度,然后查询invoice_check表,通过显示出来的结果可以看到现在已经没有invoice_name列了,变成了invoice_name_short列。

30 楼

5.3.2  修改约束
使用ALTER TABLE语句可以完成如下3类修改约束的操作。
&#61553;    向表中添加一个新的约束。
&#61553;    移除表中现有的约束。
&#61553;    启用或禁用约束。
ALTER TABLE用来处理约束的语法如下所示。

ALTER TABLE table_name
{
   ADD CONSTRAINT constraint_name constraint_definition [DISABLE] |
   DROP CONSTRAINT constraint_name |
   ENABLE [NOVALIDATE] constraint_name |
   DISABLE constraint_name
}

下面分别介绍这3种功能的实现。
1.添加约束
invoice_check这个表在创建的时候并没有指定主键,可以参考代码5.11所示的创建代码。下面的代码将使用ADD CONSTRAINT为invoice_check添加一个主键约束:

ALTER TABLE invoice_check ADD CONSTRAINT invoice_check_pk PRIMARY KEY (invoice_id);

上述代码会成功地向invoice_check添加主键约束,因为主键列是非空+唯一约束的实现,而在invoice_check表中invoice_id符合这个条件。假定invoice_id中包含两条相同的记录,执行上述的代码,将出现如下所示的异常:

ALTER TABLE invoice_check ADD CONSTRAINT invoice_check_pk PRIMARY KEY (invoice_id)
                                         *
ERROR 位于第 1 行:
ORA-02437: 无法验证 (APPS.INVOICE_CHECK_PK) - 违反主键

ADD CONSTRAINT有一个DISABLE关键字,如果不指定该关键字,那么在创建约束后将启用约束,可以通过使用该关键字来创建一个未被启用的约束。
当一个约束被禁用以后,Oracle将不对已经存在的数据值检查是否符合约束条件,因此使用ALTER TABLE语句时,即便不符合约束条件也能正确地添加约束。例如invoice_ check表的invoice_name列包含两条重复的数据,如下所示。

SQL> set linesize 300;
SQL> select * from invoice_check;
INVOICE_ID   INVOICE_TOTAL   PAYMENT_TOTAL   INVOICE_NAME
----------- -------------- --------------- ---------------
         1           200             200           Demo1
         2           300             400           Demo2
         3           300             400           This is a invoice_name field
         4           300             400           Demo2

当向invoice_check表中添加约束而不指定DISABLE时,Oracle会提示异常。如果指定了DISABLE,可以看到约束已经被成功添加,如下所示。

ALTER TABLE invoice_check ADD CONSTRAINT invoice_check_nn UNIQUE (invoice_name) DISABLE;

由于该约束被禁用,其效果就好像该约束并不存在一样,因此仍然可以向该约束插入重复的值。
下面的代码列出了一些常见的使用ALTER语句添加约束的语法:

--添加检查约束
ALTER TABLE invoice_check_others
ADD CONSTRAINT invoice_total_ck CHECK(invoice_total>=1) DISABLE
--添加外键约束
ALTER TABLE invoice_check_others
ADD CONSTRAINT invoice_fk_vendors FOREIGN KEY (vendor_id) REFERENCES vendors(vendor_id)
--添加NOT NULL约束
ALTER TABLE vendors 
ADD CONSTRAINT vendor_vendor_name_nn NOT NULL;
2.删除约束
要删除一个约束,必须得知道约束的名称。如果表使用了未指定约束名的列级别的约束定义方式,那么Oracle将会使用SYS_Cn这样的形式自动为约束指定名称,例如约束名SYS_C001118879。开发人员可以通过Toad、Oracle SQL Developer或PL/SQL Developer这样的工具来查询特定名的约束名称。
例如要删除invoice_check_nn这个约束,可以使用如下所示的语句:

ALTER TABLE invoice_check DROP CONSTRAINT invoice_check_nn;
3.启用和禁用约束
尽管可以在创建约束时使用DISABLE关键字禁用这个约束,但对于任何已经创建好的约束,都可以使用ENABLE或DISABLE关键字来进启用或者是禁用。
假定已为invoice_check表创建了invoice_check_nn这个UNIQUE约束,该约束在创建时使用DISABLE关键字进行了禁用,可以使用下面的语法启用这个约束:

ALTER TABLE invoice_check ENABLE CONSTRAINT invoice_check_nn;

当执行这行语句时,Oracle提示一个异常,如下所示。

SQL> ALTER TABLE invoice_check ENABLE CONSTRAINT invoice_check_nn;
ALTER TABLE invoice_check ENABLE CONSTRAINT invoice_check_nn
*
第 1 行出现错误:
ORA-02299: 无法验证 (SCOTT.INVOICE_CHECK_NN) - 找到重复关键字

之所以出现这个异常,是因为当启用一个约束时,默认情况下会对已经存在的记录进行检查,因为默认情况下ENABLE关键字会使用VALIDATE作为约束检查条件,所以如果不匹配约束的条件,将抛出异常。
Oracle提供了NOVALIDATE关键字,允许仅对新的记录应用约束,而不对原有的记录进行检查。但是对于UNIQUE和PRIMARY KEY约束,要使用NOVALIDATE关键字,必须对约束使用DEFERRABLE关键字,如以下代码所示。

--移除UNIQUE约束
ALTER TABLE invoice_check DROP CONSTRAINT invoice_check_nn;
--使用DEFERRABLE关键字增强一个被禁用的约束
ALTER TABLE invoice_check ADD CONSTRAINT invoice_check_nn UNIQUE (invoice_name) DEFERRABLE DISABLE;
--启用约束,对于已存在的记录不进行验证
ALTER TABLE invoice_check ENABLE NOVALIDATE CONSTRAINT invoice_check_nn;

当使用了NOVALIDATE关键字后,可以看到现在已经成功启用约束,如果向invoice_check表的invoice_name列插入已存在的记录,例如下面的代码:

SQL> INSERT INTO invoice_check VALUES(5,300,400,'Demo2');
INSERT INTO invoice_check VALUES(5,300,400,'Demo2')
*
第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (SCOTT.INVOICE_CHECK_NN)

如果要禁用一个现有的约束,可以使用DISABLE关键字,也可以在DISABLE关键字后面使用VALIDATE和NOVALIDATE关键字,其作用分别如下。
&#61553;    DISABLE VALIDATE:禁用约束,对已存在的记录进行验证。
&#61553;    DISABLE NOVALIDATE:禁用约束,不验证已存在的记录。
当直接使用DISABLE不指定验证关键字时,与使用NOVALIDATE一样,例如下面的代码将禁用invoice_check_nn约束。

ALTER TABLE invoice_check DISABLE CONSTRAINT invoice_check_nn;

如果在DISABLE关键字后面添加VALIDATE关键字,Oracle将抛出异常,提示存在重复记录,如以下代码所示。

SQL> ALTER TABLE invoice_check DISABLE VALIDATE CONSTRAINT invoice_check_nn;
ALTER TABLE invoice_check DISABLE VALIDATE CONSTRAINT invoice_check_nn
*
第 1 行出现错误:
ORA-02299: 无法验证 (SCOTT.INVOICE_CHECK_NN) - 找到重复关键字

我来回复

您尚未登录,请登录后再回复。点此登录或注册