“将表创建为选择”不保留不为空

时间:2013-07-18 19:49:59

标签: oracle create-table

我正在尝试使用Oracle的“Create Table As Select”功能来进行快速更新。我看到的问题是“Null”字段没有被保留。

我定义了下表:

create table mytable(
  accountname varchar2(40) not null,
  username varchar2(40)
 );

当我执行原始CTAS时,帐户上的NOT NULL将被保留:

 create table ctamytable as select * from mytable;

 describe ctamytable;

Name        Null     Type         
----------- -------- ------------ 
ACCOUNTNAME NOT NULL VARCHAR2(40)

USERNAME             VARCHAR2(40) 

但是,当我对accountname进行替换时,不会保留NOT NULL。

 create table ctamytable as 
   select replace(accountname, 'foo', 'foo2') accountname, 
          username 
     from mytable;

 describe ctamytable;

Name        Null Type          
----------- ---- ------------- 
ACCOUNTNAME      VARCHAR2(160) 
USERNAME         VARCHAR2(40) 

请注意,accountname字段不再为空,varchar2字段的字符数为40到160。有没有人见过这个?

2 个答案:

答案 0 :(得分:4)

这是因为您不再选择ACCOUNTNAME,它具有列定义和元数据。而是选择STRING,replace函数的结果,它没有任何元数据。这完全是一种不同的数据类型。

可能更好的方法是使用带有原始列的查询创建表,但使用WHERE子句保证0行。

然后,您可以使用实际的SELECT正常插入表格。

通过查询0行,您仍然可以获得列元数据,因此应该创建表,但不会插入任何行。确保你的WHERE条款快速,例如WHERE primary_key = -999999,你知道某个号码永远不存在。

答案 1 :(得分:2)

此处的另一个选项是在调用CREATE TABLE AS SELECT时定义列。可以列出列名并包括约束,同时排除数据类型。

示例如下所示:

create table ctamytable (
  accountname not null,
  username
)
as 
  select 
    replace(accountname, 'foo', 'foo2') accountname, 
    username 
  from mytable;

请注意,虽然此语法有效,但您不能包含数据类型。此外,明确声明所有列有点失败了使用CREATE TABLE AS SELECT的目的。