达梦8,关于参数CTAB_SEL_WITH_CONS的验证

看到管理员手册中说到这个参数,感觉比较有趣,就想来验证下,先摘录管理员手册原话如下:

如 果 用 户 通 过 单 表 的 全 表 查 询 进 行 建 表 操 作 , 则 可 以 通 过 将 INI 参 数CTAB_SEL_WITH_CONS 置为 1 进行原始表上约束的拷贝,列上能拷贝的约束包括默认值属性、自增属性、非空属性以及加密属性,表上能拷贝的约束包括唯一约束、PK 约束以及 CHECK约束。也可将 CTAB_SEL_WITH_CONS 置为 2 进行原始表上表结构、分区信息、存储信息以及表约束的拷贝,其中表约束包括唯一约束、PK 约束以及 CHECK 约束。也可将CTAB_SEL_WITH_CONS 置为 3 同时进行 1 和 2 的拷贝。

先查询一下这个参数的想信息:

SQL> select * from v$dm_ini where PARA_NAME like 'CTAB_SEL_WITH_CONS';

行号     PARA_NAME          PARA_VALUE MIN_VALUE MAX_VALUE DEFAULT_VALUE MPP_CHK SESS_VALUE FILE_VALUE

---------- ------------------ ---------- --------- --------- ------------- ------- ---------- ----------

           DESCRIPTION                                               PARA_TYPE

           --------------------------------------------------------- ---------

1          CTAB_SEL_WITH_CONS 0          0         2         0             N       0          0

           Whether to build constraints when creating table by query SYS

如上看到,这个参数最大只能支持到2,并不支持设置为3。希望管理员手册的作者在表述上可以更加严谨。实际上确实也不支持3(我在linux和windows两个平台都试了也不支持)。

SQL> alter system set 'CTAB_SEL_WITH_CONS'=3;

alter system set 'CTAB_SEL_WITH_CONS'=3;

[-838]:非法的配置参数值.

已用时间: 10.964(毫秒). 执行号:0.

而后可以创建下具体实验环境:

建表语句如下:

SQL> CREATE TABLE STUDENT(

2   NAME VARCHAR(20),

3   AGE INT PRIMARY KEY,

4   SEX VARCHAR(10) CHECK (SEX IN ('MAIL','FEMAIL')), GRADE INT CHECK (GRADE IN (7,8,9)))

5   PARTITION BY LIST(GRADE)

6   SUBPARTITION BY LIST(SEX) SUBPARTITION TEMPLATE

7   (

8   SUBPARTITION Q1 VALUES('MAIL'),

9   SUBPARTITION Q2 VALUES('FEMAIL')

10  ),

11  SUBPARTITION BY RANGE(AGE) SUBPARTITION TEMPLATE

12  (

13  SUBPARTITION R1 VALUES LESS THAN (12),

14  SUBPARTITION R2 VALUES LESS THAN (15),

15  SUBPARTITION R3 VALUES LESS THAN (MAXVALUE)

16  )

17  (

18  PARTITION P1 VALUES (7),

19  PARTITION P2 VALUES (8),

20  PARTITION P3 VALUES (9)

21  );

警告: 列表分区未包含DEFAULT,可能无法定位到分区

操作已执行

已用时间: 50.302(毫秒). 执行号:602.

插入语句如下:

insert into student VALUES ('a',10,'MAIL',7);

insert into student VALUES ('b',11,'MAIL',8);

insert into student VALUES ('c',13,'MAIL',9);

insert into student VALUES ('d',16,'MAIL',7);

commit;

实际还创建了一个非全局索引。事后验证,这个索引确实不会被支持复制。支持复制的只有其表述中所说的约束和表结构。所以,如果使用这个语句进行一些类似于表容量收缩等操作,请千万谨慎。因为可能漏掉其相关的索引或外键等。

先设置此参数为2

SQL> alter system set 'CTAB_SEL_WITH_CONS'=2;

DMSQL 过程已成功完成

已用时间: 12.958(毫秒). 执行号:625.

SQL> create table student_new as select * from student;

操作已执行

已用时间: 137.429(毫秒). 执行号:626.

表结构及约束得到了复制:

SQL> select tabledef('SYSDBA','STUDENT_NEW');

警告: 字符串截断

行号     TABLEDEF('SYSDBA','STUDENT_NEW')                                                                       

---------- -------------------------------------------------------------------------------------------------------

1          CREATE TABLE "SYSDBA"."STUDENT_NEW"

(

"NAME" VARCHAR(20),

"AGE" INT NOT NULL,

"SEX" VARCHAR(10),

"GRADE" INT,

NOT CLUSTER PRIMARY KEY("AGE"),

CHECK(SEX IN ('MAIL', 'FEMAIL'))   --约束

,CHECK(GRADE IN (7, 8, 9)))

PARTITION BY LIST("GRADE")

SUBPARTITION BY LIST("SEX") SUBPARTITION TEMPLATE

(

SUBPARTITION  "Q1"  VALUES('MAIL') STORAGE(ON "MAIN"),

SUBPARTITION  "Q2"  VALUES('FEMAIL') STORAGE(ON "MAIN")

),

SUBPARTITION BY RANGE("AGE") SUBPARTITION TEMPLATE

(

SUBPARTITION  "R1"  VALUES LESS THAN(12) STORAGE(ON "MAIN"),

SUBPARTITION  "R2"  VALUES LESS THAN(15) STORAGE(ON "MAIN"),

SUBPARTITION  "R3"  VALUES LESS THAN(MAXVALUE) STORAGE(ON "MAIN")

)

(

PARTITION  "P1"  VALUES(7)   STORAGE(ON "MAIN", CLUSTERBTR) ,

PARTITION  "P2"  VALUES(8)   STORAGE(ON "MAIN", CLUSTERBTR) ,

PARTITION 

已用时间: 2.323(毫秒). 执行号:627.

再将此参数设置为1:

SQL> alter system set 'CTAB_SEL_WITH_CONS'=1;

DMSQL 过程已成功完成

已用时间: 9.582(毫秒). 执行号:646.

SQL> create table student1 as select * from student;

操作已执行

已用时间: 9.791(毫秒). 执行号:647.

仅复制了约束,并未复制表结构:

SQL> select tabledef('SYSDBA','STUDENT1');

行号     TABLEDEF('SYSDBA','STUDENT1')                                                                         

---------- -------------------------------------------------------------------------------------------------------

1          CREATE TABLE "SYSDBA"."STUDENT1"

(

"NAME" VARCHAR(20),

"AGE" INT NOT NULL,

"SEX" VARCHAR(10),

"GRADE" INT,

NOT CLUSTER PRIMARY KEY("AGE"),

CHECK(SEX IN ('MAIL', 'FEMAIL'))

,CHECK(GRADE IN (7, 8, 9))) STORAGE(ON "MAIN", CLUSTERBTR) ;

已用时间: 0.751(毫秒). 执行号:648.

SQL> 

验证完全后,这里提一下触发器吧。因为删除表,触发器也会一起级联被删除。所以专门想尝试一下。我仅仅对表重命名,然后看表的触发器是否可用就好了。触发器创建及有效性如下:

SQL> CREATE OR REPLACE TRIGGER STUDENT_TRIGGER

2   BEFORE INSERT

3   ON STUDENT

4   FOR EACH ROW --表示行级触发器

5  

6   BEGIN

7    if :new.AGE<7 then

8    RAISE_APPLICATION_ERROR(-20001,'未到达入学年龄');

9    END if;

10  end;

11  /

操作已执行

已用时间: 9.427(毫秒). 执行号:606.

SQL> insert into student VALUES ('e',6,'MAIL',7);  --可以看到触发器已生效

insert into student VALUES ('e',6,'MAIL',7);

[-20001]:未到达入学年龄

-20001: STUDENT_TRIGGER line 8 .

已用时间: 1.497(毫秒). 执行号:0.

修改表名尝试如下:

SQL> ALTER TABLE STUDENT RENAME TO STUDENT_BAK;

操作已执行

已用时间: 29.489(毫秒). 执行号:628.

SQL> alter table student_new rename to student;

操作已执行

已用时间: 26.868(毫秒). 执行号:629.

触发器还是否生效呢?

SQL> insert into student VALUES ('e',6,'MAIL',7);

影响行数 1

失效了,实际这个触发器还是存在的,但是就是不再有效。

重新编译下试试。

SQL> CREATE OR REPLACE TRIGGER STUDENT_TRIGGER

2   BEFORE INSERT

3   ON STUDENT

4   FOR EACH ROW --表示行级触发器

5  

6   BEGIN

7    if :new.AGE<7 then

8    RAISE_APPLICATION_ERROR(-20001,'未到达入学年龄');

9    END if;

10  end;

11  /

CREATE OR REPLACE TRIGGER STUDENT_TRIGGER

BEFORE INSERT

ON STUDENT

FOR EACH ROW --表示行级触发器

BEGIN

 if :new.AGE<7 then

 RAISE_APPLICATION_ERROR(-20001,'未到达入学年龄');

 END if;

end;

第10 行附近出现错误[-3007]:替换触发器[STUDENT_TRIGGER]属性不一致.

已用时间: 0.245(毫秒). 执行号:0.

SQL> insert into student VALUES ('e',6,'MAIL',7);

影响行数 1

已用时间: 0.257(毫秒). 执行号:649.

SQL> rollback;

操作已执行

已用时间: 0.310(毫秒). 执行号:650.

SQL>

无法进行编译。只能删除此触发器重建了。实际仔细观察,会发现这里触发器已经被修改对象为STUDENT_BAK表了。这个坑在迁移时一定要注意。

达梦数据库技术社区:https://eco.dameng.com  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值