今天看到一道题,提到的这些功能属性都很熟悉,但直接这么问,确实有些含糊,实践是检验真理的唯一标准,只能通过实验,来证明我们的猜测了,
翻译一下问题,我们要验证的是,一张表上的主键、唯一约束、NOT NULL约束、外键约束,当在Oracle中通过CTAS创建一张新表的时候会不会复制过来?
创建测试表,
CREATE TABLE t1(id NUMBER PRIMARY KEY, c1 varchar2(1) NOT NULL, c2 NUMBER, c3 NUMBER UNIQUE);
CREATE TABLE t2(id NUMBER PRIMARY KEY, c1 varchar2(1) NOT NULL);
ALTER TABLE t1 ADD CONSTRAINT fk_t1_t2 FOREIGN KEY (c2) REFERENCES t2(id);
id是主键列,c1存在NOT NULL约束,c2存在外键约束,c3存在唯一约束,这里发现个DBeaver数据库客户端的显示问题,表的约束、外键视图中,都未显示c2这个外键约束,
但通过视图user_constraints,是可以找到创建的这个外键约束,
SQL> exec print_table('select constraint_name, constraint_type from user_constraints where table_name=''T1''');
CONSTRAINT_NAME : FK_T1_T2
CONSTRAINT_TYPE : R
-----------------
CONSTRAINT_NAME : SYS_C007441
CONSTRAINT_TYPE : C
-----------------
CONSTRAINT_NAME : SYS_C007442
CONSTRAINT_TYPE : P
-----------------
CONSTRAINT_NAME : SYS_C007443
CONSTRAINT_TYPE : U
-----------------PL/SQL procedure successfully completed.
CTAS创建表,
CREATE TABLE t1_1 AS SELECT * FROM t1;
可以看到,新的表只存在这个非空约束,主键、唯一约束、外键约束这几个,都没带过来,
SQL> exec print_table('select constraint_name, constraint_type, search_condition from user_constraints where table_name=''T1_1''');
CONSTRAINT_NAME : SYS_C007445
CONSTRAINT_TYPE : C
SEARCH_CONDITION : "C1" IS NOT NULL
-----------------PL/SQL procedure successfully completed.
因此,答案显而易见了。
但是,为什么是这现象?我们从Oracle官方手册,能看到一些端倪,《SQL Language Reference》谈到了CTAS对于约束的复制能力,除了上述实验中涉及到的约束类型,其他一些不能复制过来的属性,都在此进行说明,
https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_7002.htm#sthref5328
Oracle Database derives data types and lengths from the subquery. Oracle Database follows the following rules for integrity constraints and other column and table attributes:
> Oracle Database automatically defines on columns in the new table any NOT NULL constraints that have a state of NOT DEFERRABLE and VALIDATE, and were explicitly created on the corresponding columns of the selected table if the subquery selects the column rather than an expression containing the column. If any rows violate the constraint, then the database does not create the table and returns an error.
显式的NOT NULL约束自动会带到新表。
> NOT NULL constraints that were implicitly created by Oracle Database on columns of the selected table (for example, for primary keys) are not carried over to the new table.
隐式的NOT NULL约束不会带到新表,例如主键。
> In addition, primary keys, unique keys, foreign keys, check constraints, partitioning criteria, indexes, and column default values are not carried over to the new table.
另外,主键,唯一,外键,check约束,分区,索引以及列的默认值不会带到新表。
> If the selected table is partitioned, then you can choose whether the new table will be partitioned the same way, partitioned differently, or not partitioned. Partitioning is not carried over to the new table. Specify any desired partitioning as part of the CREATE TABLE statement before the AS subquery clause.
在新表上可以选择是否像旧表那样分区,或者不同的分区形式,或者创建非分区表。在AS subquery句之前指定。
> A column that is encrypted using Transparent Data Encryption in the selected table will not be encrypted in the new table unless you define the column in the new table as encrypted at create time.
TDE的列不会带到新表。
因此,像约束这种这么普通的属性,都会有这些隐藏的现象,数据库的技术领域还真是深奥,而这可能也是技术的迷人之处,碰到问题、探究问题、解决问题,乐此不疲。
近期更新的文章:
《故障树分析法(FTA)》
《"红警"游戏开源代码带给我们的震撼》
《中国四大航天发射场》
《最近碰到的一些问题》
《MySQL设置管理员密码无法生效的案例一则》
文章分类和索引:
《公众号1000篇文章分类和索引》