当心 CREATE TABLE AS

    对 DBA 而言,CREATE TABLE AS 可谓是家常便饭,顺手拈来。需不知该方式虽然简单,但疏忽也容易导致意想不到的问题。笔者前阵子就碰上
了这样的事情。由于是对原表进行克隆,且数据存储在不同的表空间,因此毫不犹豫地使用了CREATE TABLE AS,结果在运行package时,error...

--1、非空约束遗失
-->使用create table as 来创建对象
scott@CNMMBO> create table tb_dept as select * from dept where 1=0;

Table created.

scott@CNMMBO> desc dept;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 DEPTNO                                                NOT NULL NUMBER(2)
 DNAME                                                          VARCHAR2(14)
 LOC                                                            VARCHAR2(13)

scott@CNMMBO> desc tb_dept;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 DEPTNO                                                         NUMBER(2)
 DNAME                                                          VARCHAR2(14)
 LOC                                                            VARCHAR2(13)

-->从上面的desc可以看出新创建的表少了非空约束
-->下面手动为其增加非空约束,增加后与原来的表是一致的。当然使用create table as时,索引是需要单独重建的。
scott@CNMMBO> alter table tb_dept modify (deptno not null);  

Table altered.

scott@CNMMBO> drop table tb_dept;    -->删除刚刚穿件的表tb_dept

Table dropped.

--2、存在非空约束时default约束遗失
-->下面为表dept的loc列添加非空约束,且赋予default值
scott@CNMMBO> alter table dept modify (loc default 'BeiJing' not null);

Table altered.

-->为原始表新增一条记录
scott@CNMMBO> insert into dept(deptno,dname) select 50,'DEV' from dual;

1 row created.

scott@CNMMBO> commit;

Commit complete.

-->下面的查询可以看到新增记录50的loc为缺省值'BeiJing'
scott@CNMMBO> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 DEV            BeiJing

-->再次使用create table as来创建对象
scott@CNMMBO> create table tb_dept as select * from dept;

Table created.        

-->从下面可知,由于列loc存在default值,所以此时not null约束被同时赋予
scott@CNMMBO> desc tb_dept
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 DEPTNO                                                         NUMBER(2)
 DNAME                                                          VARCHAR2(14)
 LOC                                                   NOT NULL VARCHAR2(13)

scott@CNMMBO> select * from tb_dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 DEV            BeiJing 

-->为新创建的表新增记录
-->新增时发现尽管not null约束生效,但原表上设定的default值不存在了
scott@CNMMBO> insert into tb_dept(deptno,dname) select 60,'HR' from dual;
insert into tb_dept(deptno,dname) select 60,'HR' from dual
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("SCOTT"."TB_DEPT"."LOC")

scott@CNMMBO> drop table tb_dept;

Table dropped.

--3、唯一约束遗失
scott@CNMMBO> alter table dept modify (dname unique);

Table altered.

scott@CNMMBO> create table tb_dept as select * from dept;

Table created.

scott@CNMMBO> insert into tb_dept select 60,'DEV','ShangHai' from dual;

1 row created.

scott@CNMMBO> commit;

Commit complete.

scott@CNMMBO> select * from tb_dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 DEV            BeiJing
        60 DEV            ShangHai

-->有关check约束与外键约束不再演示

--4、最彻底的解决办法
scott@CNMMBO> select dbms_metadata.get_ddl('TABLE','DEPT') from dual;

DBMS_METADATA.GET_DDL('TABLE','DEPT')
--------------------------------------------------------------------------------

  CREATE TABLE "SCOTT"."DEPT"
   (    "DEPTNO" NUMBER(2,0),
        "DNAME" VARCHAR2(14),
        "LOC" VARCHAR2(13) DEFAULT 'BeiJing' NOT NULL ENABLE,
         CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
  TABLESPACE "GOEX_USERS_TBL"  ENABLE,
         UNIQUE ("DNAME")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
  TABLESPACE "GOEX_USERS_TBL"  ENABLE
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
  TABLESPACE "GOEX_USERS_TBL"

--5、演示环境
scott@CNMMBO> select * from v$version where rownum<2;

BANNER
----------------------------------------------------------------
Oracle Database 10g Release 10.2.0.3.0 - 64bit Production

--6、演示结论
-->create table as 尽管会克隆表及数据,数据是完整的,但是结构部分仅仅是部分克隆
-->create table as 会使用表上的约束被遗失或出于非正常状态
-->create table as 时,表上的索引、触发器等不会被同时克隆
-->create table as 仅作测试使用,要得到完整的结构语句,还是使用dbms_metadata.get_ddl包

-->Author: Robinson Cheng
-->Blog:   http://blog.csdn.net/robinson_0612    

更多参考:

启用用户进程跟踪

父游标、子游标及共享游标

绑定变量及其优缺点

dbms_xplan之display_cursor函数的使用

dbms_xplan之display函数的使用

执行计划中各字段各模块描述

使用 EXPLAIN PLAN 获取SQL语句执行计划

启用 AUTOTRACE 功能

函数使得索引列失效

Oracle 绑定变量窥探

时间: 2024-09-12 23:33:22

当心 CREATE TABLE AS的相关文章

CREATE TABLE – SQL Command

command CREATE TABLE – SQL CommandCreates a table having the specified fields. CREATE TABLE | DBF TableName1 [NAME LongTableName] [FREE] (FieldName1 FieldType [(nFieldWidth [, nPrecision])] [NULL | NOT NULL] [CHECK lExpression1 [ERROR cMessageText1]]

oracle中用Create Table创建表时,Storage中参数的含义!

oracle|创建 可用于:表空间.回滚段.表.索引.分区.快照.快照日志 参数名称缺省值最小值最大值说明INITIAL5(数据块)2(数据块)操作系统限定分配给Segment的第一个Extent的大小,以字节为单位,这个参数不能在alter语句中改变,如果指定的值小于最小值,则按最小值创建.NEXT5(数据块)1(数据块)操作系统限定第二个Extent的大小等于NEXT的初值,以后的NEXT值=前一NEXT大小乘以(1+PCTINCREASE/100),如果指定的值小于最小值,则按最小值创建.

ERROR 1005 (HY000): Can&#039;t create table &#039;zcxt.tb_asset&#039; (errno: 150)解决

环境 MySQL 5.1 + 命令行工具 问题 建表出现如下错误: ERROR 1005 (HY000): Can't create table 'zcxt.tb_asset' (errno: 150) 解决 1. 是否存 在SQL语法错误: 2. 外键引用的字段是否存在.

ERROR 1005 (HY000): Can&#039;t create table错误的解决

在使用MySQL的时候,在操作不当时,很容易出现 ERROR 1005 (HY000): Can't create table 这类错误.很多站长朋友可能需要排查很久才会找到问题的原因其实很简单,希望这篇文章可以对站长朋友以及Mysql初学者一点帮助. MYSQL官方提供的问题原因: 在信息中有一组[LATEST FOREIGN KEY ERROR]会有最近错误的详细描述和解决办法. Cannot find an index in the referenced table where the r

sqlite3-请教Android SQLite大神,我重复调用CREATE TABLE会将旧表覆盖吗?

问题描述 请教Android SQLite大神,我重复调用CREATE TABLE会将旧表覆盖吗? 我实现了一个DBHelper对象,在OnCreate()初始化的时候会这样处理. @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table download_info(_id integer PRIMARY KEY AUTOINCREMENT, thread_id integer)"); }

PostgreSQL Oracle 兼容性之 - rowid (CREATE TABLE WITH OIDS)

标签 PostgreSQL , Oracle , 兼容性 , 行号 , rowid , oid , ctid 背景 Oracle的数据中,通过ROWID可以定位到一条记录,当记录没有发生行迁移时,ROWID是不变的,因此即使不使用PK,也能很好的定位到一条记录. PostgreSQL中,也有行号,CTID,由BLOCK_ID和ITEM_ID组成,即哪个数据块的哪条记录. 但是PostgreSQL的引擎为多版本引擎,因此一条记录在被更新后CTID会发生变化(代表了新的版本). 不管是Oracle还

MySQL中create table语句的基本语法是_php基础

MySQL中create table语句的基本语法是:  Create [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]  [table_options] [select_statement]  TEMPORARY:该关键字表示用create table新建的表为临时表,此表在当前会话结束后将自动消失.临时表主要被应用于存储过程中,对于目前尚不支持存储过程的MySQL,该关键字一般不用.  IF NOT EX

MySQL Meta 信息与 CREATE TABLE 的对应关系

前情提要 下面四篇文章是数月之前对length的理解 MySQL Meta中的length字段 -- (1) 初始值的length计算 MySQL Meta中的length字段 -- (2) length的推导MySQL Meta中的length字段 -- (3) length的推导举例MySQL Meta中的length字段 -- (4) 玩儿MySQL代码 温故而知新,几个月后,对 length 等 meta 信息的理解又进一步,本文再记之. 混乱的MySQL定义 用"混乱"这个词

mysqldump:Couldn&#039;t execute &#039;show create table `tablename`&#039;: Table tablename&#039; doesn&#039;t exist (1146)

遇到了一个错误mysqldump: Couldn't execute 'show create table `CONCURRENCY_ERRORS`': Table INVOICE_OLD.CONCURRENCY_ERRORS' doesn't exist (1146) ###### WARNING ###### Errors reported during AutoMySQLBackup execution.. Backup failed Error log below.. Error: Co