在 oracle 中修改列 - 如何在设置为可为空之前检查列是不是可为空?

Posted

技术标签:

【中文标题】在 oracle 中修改列 - 如何在设置为可为空之前检查列是不是可为空?【英文标题】:MODIFY COLUMN in oracle - How to check if a column is nullable before setting to nullable?在 oracle 中修改列 - 如何在设置为可为空之前检查列是否可为空? 【发布时间】:2010-11-04 23:08:03 【问题描述】:

我正试图替一位同事做一些 Oracle 工作,但遇到了障碍。在尝试编写脚本将列修改为可为空时,我遇到了可爱的 ORA-01451 错误:

ORA-01451: column to be modified to NULL cannot be modified to NULL

发生这种情况是因为该列已经为 NULL。我们有几个数据库需要更新,所以在我的错误假设中,我认为将其设置为 NULL 应该可以全面确保每个人都是最新的,无论他们是否手动将此列设置为可为空。但是,对于一些已经将该列设为可为空的人来说,这显然会导致错误。

如何检查一列是否已经可以为空以避免错误?可以实现这个想法的东西:

IF( MyTable.MyColumn IS NOT NULLABLE)
   ALTER TABLE MyTable MODIFY(MyColumn  NULL);

【问题讨论】:

【参考方案1】:

您可以在 PL/SQL 中执行此操作:

declare
  l_nullable user_tab_columns.nullable%type;
begin
  select nullable into l_nullable
  from user_tab_columns
  where table_name = 'MYTABLE'
  and   column_name = 'MYCOLUMN';

  if l_nullable = 'N' then
    execute immediate 'alter table mytable modify (mycolumn null)';
  end if;
end;

【讨论】:

谢谢托尼!我得到了这个工作(有一个小修复来关闭立即执行的报价),我们现在开始营业了! 我建议每次运行此 ALTER TABLE 时都查询数据字典,这与仅处理发生的异常相比效率非常低。 Jeffrey,您可能是对的,但这是针对模式更改脚本的,因此每个数据库只运行一次。更改完成后,将不会再次运行。 使用这种方法似乎并不总是有效。我遇到了一个模式,其中列被报告为可为空,但设置 NOT NULL 仍会引发 ORA-01451。 ORA-01403:未找到数据【参考方案2】:

只需执行 alter table 并捕获异常。

DECLARE
   allready_null EXCEPTION;
   PRAGMA EXCEPTION_INIT(allready_null, -1451);
BEGIN
   execute immediate 'ALTER TABLE TAB MODIFY(COL  NULL)';
EXCEPTION
   WHEN allready_null THEN
      null; -- handle the error
END;
/

如果你不想使用 PL/SQL

    set feedback off
    set echo off
    set feedback off
    set pages 0
    set head off

    spool to_null.sql

    select 'alter table TAB modify (COL NULL);' 
    from user_tab_columns
    where table_name = 'TAB'
    and column_name = 'COL'
    and nullable = 'N';

    spool off
    set feedback on
    set echo on
    set termout on
    @@to_null.sql 
    host rm -f to_null.sql

或者只是做改变表并忽略错误。

【讨论】:

+1 表示“如果失败则捕获异常”的方法,比每次都查询数据字典更有效 只想补充一点,这种方式在PLSQL中应用非常广泛 添加 host rm -f to_null.sql (*nix) 或 host del /f to_null.sql 以避免在目录中乱扔临时文件。

以上是关于在 oracle 中修改列 - 如何在设置为可为空之前检查列是不是可为空?的主要内容,如果未能解决你的问题,请参考以下文章

为可为空的函数参数提供“null”时如何使用默认值?

如何将字符串解析为可为空的 int

mybatis怎么修改字段为空

oracle存储过程中如何判断一个字段为空

如何在 Rails 迁移中将可空列更改为不可空?

Jackson忽略空字段