5

我正在尝试使用 Oracle 的“将表创建为选择”功能进行快速更新。我看到的问题是“空”字段没有被保留。

我定义了下表:

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) 

但是,当我对帐户名进行替换时,不会保留 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 个字符。有没有人见过这个?

4

2 回答 2

4

这是因为您不再选择ACCOUNTNAME具有列定义和元数据的 。相反,您正在选择一个字符串,即replace函数的结果,它没有任何元数据。这完全是一种不同的数据类型。

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

然后您可以使用实际的SELECT.

通过查询 0 行,您仍将获得列元数据,因此应该创建表,但不会插入任何行。确保你让你的WHERE子句快一些,比如WHERE primary_key = -999999,一些你知道永远不会存在的数字。

于 2013-07-18T20:01:06.727 回答
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 的目的。

于 2013-07-19T01:50:08.600 回答