【问题标题】:How do I remove the default value from a column in oracle?oracle中如何去掉列的默认值?
【发布时间】:2020-08-27 21:05:15
【问题描述】:

表中的列有一个默认值 sysdate,我想更改它使其没有默认值,我该怎么做?

【问题讨论】:

    标签: sql oracle


    【解决方案1】:
    ALTER TABLE YourTable MODIFY YourColumn DEFAULT NULL;
    

    【讨论】:

    • 这并不完全正确。您不会删除将其设置为 NULL 的默认值。默认值不能被删除,Oracle 文档说:“如果一个列有一个默认值,那么你可以使用 DEFAULT 子句将默认值更改为 NULL,但你不能完全删除默认值。也就是说,如果一个列有曾经为其分配过默认值,那么 USER_TAB_COLUMNS 数据字典视图的 DATA_DEFAULT 列将始终显示默认值或 NULL。"
    • @Michael-O 这在功能上是否等同于没有DEFAULT 的情况? (如果是这样,人们不得不想知道为什么他们不只是使其保持一致,并且默认情况下在内部为所有内容提供NULLDEFAULT。作为最终用户,我不应该关心这样的内部细节.)
    • @jpmc26,你说得对,它们在功能上是等效的。但是,在某些情况下it affects the output of database introspection, as I wrote in my answer。 (这只是导致我得出结论认为 Oracle 是一个对程序员极其不友好的数据库的许多愚蠢的极端案例之一。)
    • @DanLenski - 我完全不同意这个结论。
    • @alexherm,怎么会这样?你能说得更具体点吗?
    【解决方案2】:

    Joe's answer 是正确的,因为带有DEFAULT NULL 的列在功能上等同于从一开始就没有为该列定义默认值:如果列没有默认值,插入新行而不为该列指定值会导致NULL

    然而,Oracle 内部清楚地代表了这两种情况,通过查看ALL_TAB_COLUMNS system view 可以看出。 (这适用于 Oracle 10.x、11.x 和 12.x,也可能适用于旧版本。)

    1. 已创建列的情况,或ALTERed,与DEFAULT NULL

      create table foo (bar varchar2(3) default null);
      
      select default_length, data_default from all_tab_columns where table_name='FOO';
      
      => default_length    data_default
         --------------    ------------
         4                 NULL
      
      select dbms_metadata.get_ddl('TABLE','FOO') from dual;
      
      => CREATE TABLE "FOO"
         (    "BAR" VARCHAR(3) DEFAULT NULL
              …
         )
      
    2. 没有指定默认值:

      create table foo (bar varchar2(3));
      
      select default_length, data_default from all_tab_columns where table_name='FOO';
      
      => default_length    data_default
         --------------    ------------
         (null)            (null)
      
      select dbms_metadata.get_ddl('TABLE','FOO') from dual;
      
      => CREATE TABLE "FOO"
         (    "BAR" VARCHAR(3)
              …
         )
      

    如上所示,在一个重要的情况下,这种原本毫无意义的区别会对 Oracle 的输出产生影响:使用DBMS_METADATA.GET_DDL() 提取表定义时。

    如果您使用GET_DDL() 内省您的数据库,那么您将获得功能相同 表的稍微不同的 DDL 输出。

    在使用GET_DDL()进行版本控制和数据库多个实例之间的比较时,这确实很烦人,没有办法避免,只能手动修改GET_DDL()的输出,或者完全重新创建没有默认值的表。

    【讨论】:

    • 我会看看 DROP DEFAULT;我不知道它是否完全等于默认 null 但似乎更具体。
    • 从 Oracle 12 开始,它没有 DROP DEFAULT ☹。这正是问题所在,也是我们需要使用DEFAULT NULL 解决它的原因。 (您在 oracle.com 上找到的任何对 DROP DEFAULT 的引用都可能与 MySQL 相关……这是一个完全独立的数据库,现在归 Oracle 所有。)
    【解决方案3】:

    做你想做的唯一方法是重新创建表。

    在 Toad 中很容易做到,只需右键单击表格并选择“重建表格”。 Toad 将创建脚本,该脚本将重命名表并重新创建一个新表。该脚本将重新创建索引、约束、外键、cmets 等...并用数据填充表。

    只需修改脚本以删除相关列之后的“默认空值”即可。

    【讨论】:

    • 可以删除列然后重新添加。 ALTER TABLE mytable DROP COLUMN mycolumn; ALTER TABLE mytable ADD mycolumn DATE;
    • 这确实有效,唯一的问题是它会将列移动到 col 列表的底部。如果要保留列顺序,请删除并重新创建表。
    【解决方案4】:

    我不知道这是否适用于旧版本的 Oracle,但我的一位同事实际上发现您可以通过以下方式将其正确重置为最初的状态(即好像从未设置过一样):

    ALTER TABLE YourTable MODIFY YourColumn DEFAULT (null);
    

    注意:如果您依赖 get_ddl 来比较表,这并不能解决问题,正如 cmets 中的 tejoe 所指出的那样,但至少 select data_default from all_tab_columns 将返回 (null) 而不是 NULL。

    【讨论】:

    • 这不是真的。 get_ddl 将返回 YourColumn DEFAULT (null) 而不仅仅是“YourColumn”
    • @tejoe :-( 你是对的,它不能解决 get_ddl 的问题,我会修改答案。如果你比较默认值,它可以解决问题,这是我需要什么。
    • 答案仍然不正确。实际上它只是一种显示解决方法。一些工具会将空值放在括号中,因此您的默认值看起来相同。但是像这样的查询“从 data_default 不为空的 all_tab_columns 中选择 data_default”仍然会找到它。这就是我所需要的。
    • 最初的问题不是关于 get_ddl 输出,所以我认为我的答案是好的,能够将默认值设置为 (null) 而不是 NULL 已经不错了,而且全部我需要的。我不认为这是一种显示解决方法,工具只是显示 all_tab_columns 系统视图的内容,其中包含 (null) 或 NULL。
    猜你喜欢
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 2023-03-23
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多