not null在oracle中启用novalidate问题

时间:2016-03-07 13:12:43

标签: sql oracle

我的表table_abc中存在数据。

列context_name是非强制性的,但现在我正在尝试修改此列并使其成为mandaroty

例如:

ALTER TABLE table_abc MODIFY CONTEXT_NAME VARCHAR2(240) NOT NULL;

这会抛出错误

第1行的错误: ORA-02296:无法启用(APPS。) - 找到空值

所以我使用novalidate,如

Alter table table_abc modify CONTEXT_NAME not null enable novalidate;

但是现在当我看到表格的结构时,它并没有将context_ame显示为非null;

Name                  Null     Type           
--------------------- -------- -------------- 
NAME                  NOT NULL VARCHAR2(700)  
ITEM_DESCRIPTION               VARCHAR2(2000) 

ITEM_TEXT_TL_15                VARCHAR2(4000) 
ITEM_DESCRLONG                 VARCHAR2(4000)     
CREATED_BY                     VARCHAR2(64)   
CREATION_DATE                  DATE           
LAST_UPDATE_DATE               DATE           
LAST_UPDATED_BY                VARCHAR2(64)   
LAST_UPDATE_LOGIN              VARCHAR2(32)   
CONTEXT_NAME                   VARCHAR2(240)   
BF_NAME          VARCHAR2(264) 

不应该context_name不为空吗?

1 个答案:

答案 0 :(得分:3)

如果要添加约束,则必须更新值以满足该约束,这意味着更新表并在现在包含null的行中填入所需的默认值。

update table_abc 
set CONTEXT_NAME = '(none)' 
where CONTEXT_NAME is null

或者,您可以向该表添加一个验证值的触发器,而不是将列更改为必需列。这样,您只需在插入或修改行时验证数据。

create or replace trigger TABLE_ABC_IUB before insert or update
on TABLE_ABC for each row
begin
  if :new.CONTEXT_NAME is null then
    raise_application_error(-20000, 'CONTEXT_NAME is required');
  end if;
end;

这将要求您在触摸行时始终填写值。您可以通过修改没有开始使用CONTEXT_NAME的行来稍微改进条件。下面的触发器应该为新行和从值更新为NULL的行强制执行值。

create or replace trigger TABLE_ABC_IUB before insert or update
on TABLE_ABC for each row
begin
  if :new.CONTEXT_NAME is null and (inserting or :old.CONTEXT_NAME is not null) then
    raise_application_error(-20000, 'CONTEXT_NAME is required');
  end if;
end;

当然,您可以只为:new.CONTEXT_NAME分配一个值,而不是引发异常。