【问题标题】:"Create table as select" does not preserve not null“创建表作为选择”不保留不为空
【发布时间】:2013-07-17 22:41:53
【问题描述】:

我正在尝试使用 Oracle 的“将表创建为选择”功能进行快速更新。我看到的问题是“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) 

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

【问题讨论】:

    标签: oracle create-table


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 无需冒险使用幻数匹配行,您只需将 WHERE 子句设置为 1=2。
    • 谢谢,选角的解释很有道理。我正在尝试进行模式范围的比较,NOT NULL 没有出现作为误报。我需要找到另一种方法来确定 Null 列。
    • @Ben 是的,我们过去常常这样做,但我不确定它是否普遍适用于其他数据库。
    【解决方案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 的目的。

    【讨论】:

    • 再次阅读问题后,我意识到我并没有真正解决您遇到的原始问题,但它确实提供了有关使用 CTAS 的更多信息。
    • 谢谢迈克。我正在通过 Java 完成所有这些工作。最后,我在运行 CTAS 之前存储了所有 NOT NULL 约束,然后重新应用它们。
    猜你喜欢
    • 2016-01-04
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    相关资源
    最近更新 更多