我有一张包含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
答案 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;