Oracle:动态设置表中的所有NOTNULL列以允许NULL
我有一个包含75+列的表。 几乎所有列都具有NOTNULL约束 如果执行一个巨大的ALTERTABLE modify语句(每个列都在其中),我会得到一个错误,大致是这样说的:“您不能将此字段设置为NULL,因为它已经为NULL” 我必须对几个表执行此操作,因此希望有一个动态解决方案 我是否可以动态查找所有不为NULL的列,并将它们设置为NULL 我见过几个类似的问题,但找不到Oracle SQL的解决方案。Oracle:动态设置表中的所有NOTNULL列以允许NULL,oracle,nullable,Oracle,Nullable,我有一个包含75+列的表。 几乎所有列都具有NOTNULL约束 如果执行一个巨大的ALTERTABLE modify语句(每个列都在其中),我会得到一个错误,大致是这样说的:“您不能将此字段设置为NULL,因为它已经为NULL” 我必须对几个表执行此操作,因此希望有一个动态解决方案 我是否可以动态查找所有不为NULL的列,并将它们设置为NULL 我见过几个类似的问题,但找不到Oracle SQL的解决方案。 这是一个测试表,有两个非空列和一个空列: create table zzz_mark_t
这是一个测试表,有两个非空列和一个空列:
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.
现在,不再是空的:
desc zzz_mark_test_me
Name Null Type
---------- ---- ------------
CUST_ID VARCHAR2(20)
CUST_NAME VARCHAR2(20)
CUST_PHONE VARCHAR2(20)
您可以使用此过程。在运行之前,您可以首先注释掉包含“executeimmediate”的行,以查看它执行什么。 第一个参数是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;
不确定为什么会收到该消息,除非您试图将一个已经可以为null的列更改为null。我刚刚用4列表做了一个测试,所有列都不为NULL,并在所有4列上运行alter以使其为NULL—工作正常。你能发布一个小的工作样本来重新创建你的问题吗?将它保留在一个4列4行的表中(这将足够大,我们可以看到问题)。包括创建表、插入、更改脚本。当然,这不过是@Mark Stewart写的,但我同时准备了这个解决方案,并使用过程避免了所有这些复制/粘贴。是的,我很懒,永远记不起execute immediate的PL/SQL语法;我还喜欢在执行之前看到生成的内容。:)我很欣赏这个答案附带的迷你教程!如果愿意,可以对其进行编辑,使executeimmediate语句进入其中。那么这就是你和Pounder的答案的两个世界中最好的。无论如何,谢谢你!