我的Oracle 9i学习日志(18)-- 维护数据完整性.b

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

创建禁止性约束:

disable 关键字即可。
SQL> create table t(id int, name char(10));
 
表已创建。
 
SQL> desc t
  名称                                        是否为空 类型
 ----------------------------------------- -------- -------------------------
 
 ID                                                 NUMBER(38)
 NAME                                               CHAR(10)
 
SQL> alter table t add constraint uq_t_id unique(id) disable;
 
表已更改。
 
SQL> insert into t values(0,'aaa');
 
已创建  1  行。
 
SQL> insert into t values(0,'aaa');
 
已创建  1  行。
 
SQL>
SQL> insert into t values(0,'aaa');
 
已创建  1  行。
 
SQL> insert into t values(0,'aaa');
 
已创建  1  行。
 
SQL> select * from t;
 
        ID NAME
---------- --------------------------------------------------
         0 aaa
         0 aaa
         0 aaa
         0 aaa
启用约束:
SQL> delete from t;
 
已删除 4 行。
 
SQL> alter table t enable unique;
alter table t enable unique
                          *
ERROR  位于第  1  :
ORA-00906: missing left parenthesis
 
 
SQL> alter table t enable unique(id);
 
表已更改。
 
SQL> insert into t values(0,'aaa');
 
已创建  1  行。
 
SQL> insert into t values(0,'aaa');
insert into t values(0,'aaa')
*
ERROR  位于第  1  :
ORA-00001: unique constraint (LUO.UQ_T_ID) violated
 
SQL> select object_name,object_type from user_objects;
 
OBJECT_NAME                    OBJECT_TYPE
------------------------------ ------------------------------------
BONUS                          TABLE
CUSTOMERS                      TABLE
DINGDAN                        TABLE
ORDERS                         TABLE
PK_CUST                        INDEX
T                              TABLE
UQ_EMP_ID                      INDEX
UQ_T_ID                        INDEX
 
已选择 8 行。
 
 
SQL> drop table t;
 
表已丢弃。
SQL> create table t(id int, name char(10));
 
表已创建。
 
SQL> alter table t add constraint pk_t_id primary key(id) disable;
 
表已更改。
 
SQL> select object_name,object_type from user_objects;
 
OBJECT_NAME                    OBJECT_TYPE
------------------------------ ------------------------------------
BONUS                          TABLE
CUSTOMERS                      TABLE
DINGDAN                        TABLE
ORDERS                         TABLE
PK_CUST                        INDEX
T                              TABLE
UQ_EMP_ID                      INDEX
 
已选择 7 行。
 
SQL> insert into t values(1,'aaa');
 
已创建  1  行。
 
SQL> insert into t values(1,'bbb');
 
已创建  1  行。
 
SQL> commit;
 
提交完成。
 
SQL> select * from t;
 
        ID NAME
---------- --------------------------------------------------
         1 aaa
         1 bbb
 
SQL> delete from t where name='bbb';
 
已删除  1  行。
 
SQL> commit ;
 
提交完成。
 
SQL> alter table t enable primary key;                           # 启用主键约束可以不用带列名。
 
表已更改。
 
SQL> insert into t values(1,'bbb');
insert into t values(1,'bbb')
*
ERROR  位于第  1  :
ORA-00001: unique constraint (LUO.PK_T_ID) violated
 
 
SQL> insert into t values(2,'bbb');
 
已创建  1  行。
 
SQL> commit ;
 
提交完成。
 
SQL> select * from t;
 
        ID NAME
---------- --------------------------------------------------
         1 aaa
         2 bbb
 
SQL> select object_name,object_type from user_objects;
 
OBJECT_NAME                    OBJECT_TYPE
------------------------------ ------------------------------------
BONUS                          TABLE
CUSTOMERS                      TABLE
DINGDAN                        TABLE
ORDERS                         TABLE
PK_CUST                        INDEX
PK_T_ID                        INDEX
T                              TABLE
UQ_EMP_ID                      INDEX
 
已选择 8 行。
 
SQL> alter table t disable primary key;                          # 再次禁用。
 
表已更改。
 
SQL> select object_name,object_type from user_objects;
 
OBJECT_NAME                    OBJECT_TYPE
------------------------------ ------------------------------------
BONUS                          TABLE
CUSTOMERS                      TABLE
DINGDAN                        TABLE
ORDERS                         TABLE
PK_CUST                        INDEX
T                              TABLE
UQ_EMP_ID                      INDEX
 
已选择 7 行。                                     # 索引消失。
删除约束:
Alter table bonus drop constraint ck_bonus;
删除 unique 或主键约束时,如果是被引用为外键的则带上 cascade 参数,删除 unique 约束同时删除了子表的外键约束。
Alter table bonus drop primary key cascade;
实验:
SQL> select constraint_name,status,validated from user_constraints;
 
CONSTRAINT_NAME                STATUS           VALIDATED
------------------------------ ---------------- --------------------------
SYS_C002763                    ENABLED          VALIDATED
CK_BONUS                       ENABLED          VALIDATED
CK_BONUS2                      ENABLED          VALIDATED
UQ_EMP_ID                      ENABLED          VALIDATED
PK_CUST                        ENABLED          VALIDATED
FK_CUST                        ENABLED          VALIDATED
CK_DPTID                       ENABLED          VALIDATED
 
已选择 7 行。
 
SQL> alter table bonus drop constraint ck_bonus2;
 
表已更改。
 
SQL> select constraint_name,status,validated from user_constraints;
 
CONSTRAINT_NAME                STATUS           VALIDATED
------------------------------ ---------------- --------------------------
SYS_C002763                    ENABLED          VALIDATED
CK_BONUS                       ENABLED          VALIDATED
UQ_EMP_ID                      ENABLED          VALIDATED
PK_CUST                        ENABLED          VALIDATED
FK_CUST                        ENABLED          VALIDATED
CK_DPTID                       ENABLED          VALIDATED
 
已选择 6 行。
 
SQL> alter table customers drop primary key cascade;
 
表已更改。
 
SQL> select constraint_name,status,validated from user_constraints;
 
CONSTRAINT_NAME                STATUS           VALIDATED
------------------------------ ---------------- --------------------------
SYS_C002763                    ENABLED          VALIDATED
CK_BONUS                       ENABLED          VALIDATED
UQ_EMP_ID                      ENABLED          VALIDATED
CK_DPTID                       ENABLED          VALIDATED
 
约束状态:

5
可以启用 (ENABLE)  或禁用 (DISABLE)  完整性约束。如果启用某个约束,则在数据库中输入或更新数据时,就会对数据进行检查。禁止输入不符合约束规则的数据。如果禁用某个约束,则可以在数据库中输入不符合约束规则的数据。完整性约束可处于以下状态之一:
• DISABLE NOVALIDATE
• DISABLE VALIDATE
• ENABLE NOVALIDATE
• ENABLE VALIDATE
DISABLE NOVALIDATE :不检查处于 DISABLE NOVALIDATE  状态的约束。表中的数据(包括输入或更新的新数据)可以不符合约束所定义的规则。
DISABLE VALIDATE :当约束处于此状态时,不允许对受约束的列进行任何修改。另外,约束上的索引将被删除并且禁用约束。注:如果约束可延迟,则不删除索引。
ENABLE NOVALIDATE :如果约束处于此状态,则不能输入违反约束的新数据。但是,表可能包含无效的数据,即数据违反约束。启用处于 NOVALIDATE  状态的约束对正在上载有效 OLTP  数据的数据仓库配置是非常有用的。
ENABLE VALIDATE :如果约束处于此状态,则不能将违反约束的行插入到表中。但是,禁用该约束时,可以插入此类行。此类行称为该约束的例外。如果约束处于 ENABLE NOVALIDATE  状态,则在禁用约束时输入的数据所引起的违反情况仍然存在。要将约束置于已验证状态,必须更新或删除违反约束的行。
当某一约束由禁用状态更改为 ENABLE VALIDATE  时,将锁定表并对表中的所有数据进行一致性检查。这可能会引起 DML  操作(如等待数据加载),因此,建议先从禁用状态转为 ENABLE NOVALIDATE ,然后再转为 ENABLE VALIDATE
这些状态之间的转换须符合以下规则:
•  除非指定 NOVALIDATE ,否则 ENABLE  表示 VALIDATE
•  除非指定 VALIDATE ,否则 DISABLE  表示 NOVALIDATE
• VALIDATE  NOVALIDATE  没有缺省的 ENABLE  DISABLE  状态。
•  当唯一键或主键从 DISABLE  状态转为 ENABLE  状态且没有现有索引时,将自动创建唯一索引。(如果索引可延迟,则将存在异常。)与此类似,当唯一键或主键从 ENABLE  转为 DISABLE  且是使用唯一索引启用时,则删除该唯一索引。
•  当任何约束从 NOVALIDATE  状态转为 VALIDATE  状态时,必须检查所有的数据。但是,从 VALIDATE  转为 NOVALIDATE  时,将忽略数据已经过检查这一事实。
•  将单个约束从 ENABLE NOVALIDATE  状态转为 ENABLE VALIDATE  状态时,并不禁止使用读取、写入或其它 DDL  语句。
 
SQL> select constraint_name,table_name,status,validated from user_constraints;
 
CONSTRAINT_NAME TABLE_NAME           STATUS           VALIDATED
--------------- -------------------- ---------------- -------------------------
 
CK_BONUS        BONUS                ENABLED          VALIDATED
UQ_EMP_ID       BONUS                ENABLED          VALIDATED
 
SQL> desc t
  名称                                        是否为空 类型
 ----------------------------------------- -------- ---------------------------
 ID                                                 NUMBER(38)
 NAME                                               CHAR(10)
 DPT_ID                                             NUMBER(38)
 
SQL> alter table t add constraint ck_dptid check(dpt_id>=10) disable;
 
表已更改。
 
SQL> insert into t values(1,'aaa ',1);
 
已创建  1  行。
 
SQL> insert into t values(2,'bbb',2);
 
已创建  1  行。
 
SQL> insert into t values(3,'ccc',3);
 
已创建  1  行。
 
SQL> commit;
 
提交完成。
 
SQL> select * from t;
 
        ID NAME                                                   DPT_ID
---------- -------------------------------------------------- ----------
         1 aaa                                                         1
         2 bbb                                                         2
         3 ccc                                                         3
 
SQL> alter table t enable novalidate constraint ck_dptid;
 
表已更改。
 
SQL> select constraint_name,table_name,status,validated from user_constraints;
 
CONSTRAINT_NAME TABLE_NAME           STATUS           VALIDATED
--------------- -------------------- ---------------- -------------------------
 
CK_BONUS        BONUS                ENABLED          VALIDATED
UQ_EMP_ID       BONUS                ENABLED          VALIDATED
CK_DPTID        T                    ENABLED          NOT VALIDATED
 
SQL> insert into t values(3,'ddd',4);
insert into t values(3,'ddd',4)
*
ERROR  位于第  1  :
ORA-02290: check constraint (LUO.CK_DPTID) violated
 
SQL> insert into t values(3,'ddd',11);
 
已创建  1  行。
# 启用 enable novalidate 状态成功。
 
SQL> alter table t add constraint pk_t_id primary key(id) disable;
 
表已更改。
 
SQL> select constraint_name,table_name,status,validated from user_constrai
 
CONSTRAINT_NAME TABLE_NAME           STATUS           VALIDATED
--------------- -------------------- ---------------- --------------------
 
CK_BONUS        BONUS                ENABLED          VALIDATED
UQ_EMP_ID       BONUS                ENABLED          VALIDATED
CK_DPTID        T                    ENABLED          NOT VALIDATED
PK_T_ID         T                    DISABLED         NOT VALIDATED
 
SQL> select * from t;
 
        ID NAME                                                   DPT_ID
---------- -------------------------------------------------- ----------
         1 aaa                                                         1
         2 bbb                                                         2
         3 ccc                                                         3
         3 ddd                                                        11
 
SQL> alter table t enable novalidate primary key;
alter table t enable novalidate primary key
*
ERROR  位于第  1  :
ORA-02437: cannot validate (LUO.PK_T_ID) - primary key violated
# 报错的原因是因为启用主键约束后会创建一个非唯一性索引,但表中有重复值,索引创建不成功。解决方法可以删除表中主键列的重复值,或用下面的方法。
 
SQL> create index t_id on t(id);
 
索引已创建。
 
SQL> select object_name,object_type from user_objects;
 
OBJECT_NAME                    OBJECT_TYPE
------------------------------ ------------------------------------
BONUS                          TABLE
CUSTOMERS                      TABLE
ORDERS                         TABLE
T                              TABLE
T_ID                           INDEX
UQ_EMP_ID                     INDEX
 
已选择 6 行。
 
SQL> alter table t enable novalidate primary key;
 
表已更改。
 
SQL> insert into t values(2,'eee',12);
insert into t values(2,'eee',12)
*
ERROR  位于第  1  :
ORA-00001: unique constraint (LUO.PK_T_ID) violated
 
 
SQL> insert into t values(4,'eee',12);
 
已创建  1  行。
 
当有大量数据处理时,一致性约束同索引一样会降低数据库性能。因此,可以按以下方法提高性能。

6
约束检查时间:

7
在约束定义完成以后, nondeferred deferred 不能相互转变。
SET CONSTRAINTS  语句用于将特定事务处理的约束设置为 DEFERRED  IMMEDIATE
可以使用此语句设置约束名称列表或约束的模式。 SET CONSTRAINTS  模式将一直持续到事务处理完成或者另一个 SET CONSTRAINTS  语句重置模式。 SET CONSTRAINTS  语句不允许在触发器内部使用。
ALTER SESSION  语句还包含将约束设置为 IMMEDIATE  DEFERRED  的子句 SET CONSTRAINTS 。此命令缺省为设置所有 (ALL)  可延迟的约束(不能指定约束名称列表)。
ALTER SESSION SET CONSTRAINTS  语句仅适用于当前的会话。
ALTER SESSION
SET CONSTRAINT[S] =
{IMMEDIATE|DEFERRED|DEFAULT}
SET CONSTRAINT | CONSTRAINTS
{constraint |ALL }
{IMMEDIATE|DEFERRED}
实验:
SQL> create table t(id int,name char(10),dpt_id int);
 
表已创建。
 
SQL> desc t;
  名称                                        是否为空 类型
 ----------------------------------------- -------- ----------------------
 
 ID                                                 NUMBER(38)
 NAME                                               CHAR(10)
 DPT_ID                                             NUMBER(38)
 
SQL> alter table t add constraint pk_t_id primary key(id);
 
表已更改。
 
SQL> select index_name,uniqueness from user_indexes;
 
INDEX_NAME                                                   UNIQUENESS
------------------------------------------------------------ -------------
PK_T_ID                                                      UNIQUE
 
SQL> alter table t drop primary key;
 
表已更改。
 
SQL> alter table t add constraint pk_t_id primary key(id) deferrable;
 
表已更改。
 
SQL> select index_name,uniqueness from user_indexes;
 
INDEX_NAME                                                   UNIQUENESS
------------------------------------------------------------ -------------
PK_T_ID                                                      NONUNIQUE
 
SQL> select object_name,object_type from user_objects;
 
OBJECT_NAME                    OBJECT_TYPE
------------------------------ ------------------------------------
PK_T_ID                        INDEX
T                              TABLE
已选择 6 行。
 
SQL> alter table t disable primary key;
 
表已更改。
 
SQL> select object_name,object_type from user_objects;
 
OBJECT_NAME                    OBJECT_TYPE
------------------------------ ------------------------------------
PK_T_ID                        INDEX
T                              TABLE
 
已选择 6 行。
# 如果索引是非唯一性索引,在 disable 主键约束时,不会删除相应索引。
SQL> insert into t values(1,'aaa',1);
 
已创建  1  行。
 
SQL> insert into t values(1,'aaa',1);
 
已创建  1  行。
 
SQL> commit;
 
提交完成。
 
SQL> select constraint_name,table_name,status,validated from user_constrai
 
CONSTRAINT_NAME TABLE_NAME           STATUS           VALIDATED
--------------- -------------------- ---------------- --------------------
PK_T_ID         T                    DISABLED         NOT VALIDATED
 
SQL> alter table t enable novalidate primary key;
 
表已更改。
 
SQL> select constraint_name,table_name,status,validated from user_constrai
 
CONSTRAINT_NAME TABLE_NAME           STATUS           VALIDATED
--------------- -------------------- ---------------- --------------------
PK_T_ID         T                    ENABLED          NOT VALIDATED
 
SQL> insert into t values(1,'aaa',1);
insert into t values(1,'aaa',1)
*
ERROR  位于第  1  :
ORA-00001: unique constraint (LUO.PK_T_ID) violated
 
 
SQL> select * from t;
 
        ID NAME                                                   DPT_ID
---------- -------------------------------------------------- ----------
         1 aaa                                                         1
         1 aaa                                                         1
 
SQL> set constraints all deferred;
 
约束条件已设置。
 
SQL> insert into t values(1,'aaa',1);
 
已创建  1  行。
 
SQL> insert into t values(1,'aaa',1);
 
已创建  1  行。
 
SQL> insert into t values(1,'aaa',1);
 
已创建  1  行。
 
SQL> select * from t;
 
        ID NAME                                                   DPT_ID
---------- -------------------------------------------------- ----------
         1 aaa                                                         1
         1 aaa                                                         1
         1 aaa                                                         1
         1 aaa                                                         1
         1 aaa                                                         1
 
SQL> commit;
commit
*
ERROR  位于第  1  :
ORA-02091: transaction rolled back
ORA-00001: unique constraint (LUO.PK_T_ID) violated









本文转自 d185740815 51CTO博客,原文链接:http://blog.51cto.com/luotaoyang/293804,如需转载请自行联系原作者
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
打赏
0
0
0
0
235
分享
相关文章
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
在YMP校验过程中,从yashandb同步至Oracle的数据出现timestamp(0)字段不一致问题。原因是yashandb的timestamp(x)存储为固定6位小数,而Oracle的timestamp(0)无小数位,同步时会截断yashandb的6位小数,导致数据差异。受影响版本:yashandb 23.2.7.101、YMP 23.3.1.3、YDS联调版本。此问题会导致YMP校验数据内容不一致。
【YashanDB 知识库】通过 dblink 查询 Oracle 数据时报 YAS-07301 异常
客户在使用 YashanDB 通过 yasql 查询 Oracle 数据时,遇到 `YAS-07301 external module timeout` 异常,导致 dblink 功能无法正常使用,影响所有 YashanDB 版本。原因是操作系统资源紧张,无法 fork 新子进程。解决方法包括释放内存、停掉不必要的进程或增大进程数上限。分析发现异常源于 system() 函数调用失败,返回 -1,通常是因为 fork() 失败。未来 YashanDB 将优化日志信息以更好地诊断类似问题。
【YashanDB知识库】Flink CDC实时同步Oracle数据到崖山
本文介绍通过Flink CDC实现Oracle数据实时同步至崖山数据库(YashanDB)的方法,支持全量与增量同步,并涵盖新增、修改和删除的DML操作。内容包括环境准备(如JDK、Flink版本等)、Oracle日志归档启用、用户权限配置、增量日志记录设置、元数据迁移、Flink安装与配置、生成Flink SQL文件、Streampark部署,以及创建和启动实时同步任务的具体步骤。适合需要跨数据库实时同步方案的技术人员参考。
【YashanDB知识库】Flink CDC实时同步Oracle数据到崖山
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
【YashanDB知识库】通过dblink查询Oracle数据时报YAS-07301异常
【YashanDB知识库】通过dblink查询Oracle数据时报YAS-07301异常
【YashanDB 知识库】通过 dblink 查询 Oracle 数据时报 YAS-07301 异常
某客户在使用 YashanDB 通过 yasql 查询 Oracle 数据时,遇到 `YAS-07301 external module timeout` 异常,导致 dblink 功能无法正常使用,影响所有版本。问题源于操作系统资源紧张,无法 fork 新子进程。解决方法包括释放内存、停掉不必要的进程或增大进程数上限。分析发现异常原因为系统调用 fork() 失败。经验总结:优化日志记录,提供更多异常信息。
【YashanDB知识库】YMP校验从yashandb同步到oracle的数据时,字段timestamp(0)出现不一致
【YashanDB知识库】YMP校验从yashandb同步到oracle的数据时,字段timestamp(0)出现不一致
Mysql、Oracle审计日志的开启
通过上述步骤,可以在 MySQL 和 Oracle 数据库中启用和配置审计日志。这些日志对于监控数据库操作、提高安全性和满足合规性要求非常重要。确保正确配置审计参数和策略,定期查看和分析审计日志,有助于及时发现并处理潜在的安全问题。
163 11
【赵渝强老师】Oracle的控制文件与归档日志文件
本文介绍了Oracle数据库中的控制文件和归档日志文件。控制文件记录了数据库的物理结构信息,如数据库名、数据文件和联机日志文件的位置等。为了保护数据库,通常会进行控制文件的多路复用。归档日志文件是联机重做日志文件的副本,用于记录数据库的变更历史。文章还提供了相关SQL语句,帮助查看和设置数据库的日志模式。
156 1
【赵渝强老师】Oracle的控制文件与归档日志文件
【赵渝强老师】Oracle的参数文件与告警日志文件
本文介绍了Oracle数据库的参数文件和告警日志文件。参数文件分为初始化参数文件(PFile)和服务器端参数文件(SPFile),在数据库启动时读取并分配资源。告警日志文件记录了数据库的重要活动、错误和警告信息,帮助诊断问题。文中还提供了相关视频讲解和示例代码。
140 1

热门文章

最新文章

推荐镜像

更多
下一篇
oss创建bucket
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等