Oracle:动态设置表中的所有NOT NULL列以允许NULL

时间:2015-02-06 20:47:33

标签: oracle nullable

我有一张包含75多列的表格。 几乎所有列都具有NOT NULL约束。

如果做一个巨大的alter table modify语句(其中包含每一列),我会收到一条错误,说明"你不能将此字段设置为NULL,因为它已经是NULL& #34;

我必须为几个表执行此操作,因此更愿意使用动态解决方案。

我可以动态查找所有非NULL的列,并将它们设置为NULL吗?

我已经看过几个这样的类似问题,但无法找到Oracle SQL的解决方案。 Modify all columns in a table to 'not null' no matter what

2 个答案:

答案 0 :(得分:4)

这是一个测试表,有两个非空列和一个空列:

create table zzz_mark_test_me (
     cust_id varchar2(20) not null, 
     cust_name varchar2(20) null,  
     cust_phone varchar2(20) not null
);

table ZZZ_MARK_TEST_ME created.

desc zzz_mark_test_me

Name       Null     Type         
---------- -------- ------------ 
CUST_ID    NOT NULL VARCHAR2(20) 
CUST_NAME           VARCHAR2(20) 
CUST_PHONE NOT NULL VARCHAR2(20) 

现在调用此SQL:

select 'alter table ' || table_name || 
    ' modify (' || column_name || ' null );' 
from user_tab_columns 
where table_name='ZZZ_MARK_TEST_ME' and nullable='N' 
order by column_id;

产生这个:

alter table ZZZ_MARK_TEST_ME modify (CUST_ID null );
alter table ZZZ_MARK_TEST_ME modify (CUST_PHONE null );

将输出复制/粘贴到SQL * Plus等中并调用:

alter table ZZZ_MARK_TEST_ME modify (CUST_ID null );
table ZZZ_MARK_TEST_ME altered.

alter table ZZZ_MARK_TEST_ME modify (CUST_PHONE null );
table ZZZ_MARK_TEST_ME altered.

现在,不再是NOT NULL:

desc zzz_mark_test_me
Name       Null Type         
---------- ---- ------------ 
CUST_ID         VARCHAR2(20) 
CUST_NAME       VARCHAR2(20) 
CUST_PHONE      VARCHAR2(20) 

答案 1 :(得分:4)

您可以使用此程序。在运行之前,您可以先注释掉包含“execute immediate”的行,以查看它执行的内容。 第一个参数是schema_name,第二个是table_name。

create or replace procedure proc_null(t_owner in varchar2, t_name in varchar2) as 
  v_exec_imm varchar2(1000);
begin
  for o in (select owner, column_name from all_tab_cols where owner=t_owner and table_name=t_name and nullable = 'N')
  loop
    v_exec_imm := 'alter table '||t_owner||'.'||t_name||' modify ('||o.column_name||' null) ';
    execute immediate v_exec_imm;  -- comment this line if You want, modifies table
    dbms_output.put_line( v_exec_imm );
  end loop;
end proc_null;