Oracle:动态设置 Table 中的所有 NOT NULL 列以允许 NULL
Oracle: Dynamically set all NOT NULL columns in a Table to allow NULL
我有一个 table,里面有超过 75 列。
几乎所有列都有 NOT NULL 约束。
如果执行一个巨大的 alter table 修改语句(其中的每一列),我会收到一条错误消息,内容类似于 "You can't set this field to NULL, because it already is NULL"
我必须这样做几个 table 秒,所以我更愿意有一个动态的解决方案。
我能否动态找到所有非 NULL 的列,并将它们设置为 NULL?
我见过几个类似的类似问题,但找不到针对 Oracle SQL 的解决方案。
Modify all columns in a table to 'not null' no matter what
这是一个测试 table,有两个非空列和一个空列:
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 );
Copy/paste 输出到 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)
您可以使用此程序。您可以先注释掉包含 "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;
我有一个 table,里面有超过 75 列。 几乎所有列都有 NOT NULL 约束。
如果执行一个巨大的 alter table 修改语句(其中的每一列),我会收到一条错误消息,内容类似于 "You can't set this field to NULL, because it already is NULL"
我必须这样做几个 table 秒,所以我更愿意有一个动态的解决方案。
我能否动态找到所有非 NULL 的列,并将它们设置为 NULL?
我见过几个类似的类似问题,但找不到针对 Oracle SQL 的解决方案。 Modify all columns in a table to 'not null' no matter what
这是一个测试 table,有两个非空列和一个空列:
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 );
Copy/paste 输出到 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)
您可以使用此程序。您可以先注释掉包含 "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;