Oracle:动态设置表中的所有 NOT NULL 列以允许 NULL
Posted
技术标签:
【中文标题】Oracle:动态设置表中的所有 NOT NULL 列以允许 NULL【英文标题】:Oracle: Dynamically set all NOT NULL columns in a Table to allow NULL 【发布时间】:2015-02-06 20:47:33 【问题描述】:我有一个包含 75 列以上的表格。 几乎所有的列都有 NOT NULL 约束。
如果执行一个巨大的 alter table modify 语句(其中包含每一列),我会收到一条错误消息,类似于“您不能将此字段设置为 NULL,因为它已经是 NULL”
我必须为多个表执行此操作,因此希望有一个动态解决方案。
能否动态查找所有不为 NULL 的列,并将它们设置为 NULL?
我见过几个类似的问题,但找不到 Oracle SQL 的解决方案。 Modify all columns in a table to 'not null' no matter what
【问题讨论】:
不确定为什么会收到该消息,除非您尝试将已经可以为 NULL 的列更改为 NULLable。我刚刚对 4 列表进行了测试,所有列都不是 NULL,然后在所有 4 列上运行 alter 到 NULL - 工作正常。您可以发布一个小的工作示例来重新创建您的问题吗?将其保留为 4 列 4 行表(这将足够大,我们可以看到问题)。包括创建表、插入、更改脚本。 【参考方案1】:这是一个测试表,有两个非空列,一个空列:
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)
【讨论】:
我很欣赏这个答案附带的迷你教程!如果你愿意,你可以编辑它,以便执行立即语句进入那里。然后,从您和 Ponder 的答案中,这是两全其美的。无论如何,谢谢!【参考方案2】:您可以使用此程序。在运行之前,您可以先注释掉包含“立即执行”的行以查看它执行的内容。 第一个参数是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;
【讨论】:
当然这只不过是@Mark Stewart 写的,但我同时准备了这个解决方案,并且使用过程可以避免所有这些复制/粘贴。 是的,我很懒,永远记不起立即执行的 PL/SQL 语法;而且我也喜欢在执行之前查看生成的内容。 :)以上是关于Oracle:动态设置表中的所有 NOT NULL 列以允许 NULL的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 12c - 根据不同表中的值动态生成 where 子句