2015-02-06 68 views
3

我有一個包含75列以上的表。 幾乎所有的列都有NOT NULL約束。Oracle:動態設置表中的所有NOT NULL列以允許NULL

如果做一個巨大的ALTER TABLE語句修改(與在那裏的每一列),我得到一個錯誤,沿着線的東西:「你不能把這個字段設置爲NULL,因爲它已經是NULL」

我必須爲多個表執行此操作,因此更願意提供動態解決方案。

我可以動態地找到所有不是NULL的列,並將它們設置爲NULL?

我見過這樣的類似問題,但找不到Oracle SQL的解決方案。 Modify all columns in a table to 'not null' no matter what

+0

不知道爲什麼你會得到該消息,除非您試圖將列更改爲已爲NULLable的NULLable。我只是做了一個4列表的測試,所有列NOT NULL,並且將所有4列的變化都改爲NULL - 工作正常。你能發佈一個小樣本,重新創建你的問題嗎?將它保存到4列,4行的表格(這將足夠大,我們可以看到問題)。包括創建表,插入,更改腳本。 – Ditto 2015-02-06 21:07:36

回答

3

下面是測試表,有兩個NOT NULL列,和一個空列:

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) 
+0

我很欣賞這個答案附帶的迷你教程!如果你願意,你可以編輯它,以便執行即時語句進入。那麼這是你和韋德答案中兩個世界中最好的。無論如何,謝謝! – matrixugly 2015-02-10 21:14:13

4

您可以使用此過程。在運行之前,您可以首先註釋包含「立即執行」的行以查看它執行的內容。 第一個參數是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; 
+0

當然,這只不過是@Mark Stewart寫的,但我同時準備了這個解決方案,並使用避免所有這些複製/粘貼的過程。 – 2015-02-06 22:48:50

+0

是的,我很懶,不能記住立即執行的PL/SQL語法;我也喜歡看它在執行之前生成的內容。 :) – 2015-02-07 23:52:48

+0

加1給你和馬克的答案。謝謝您的幫助 :) – matrixugly 2015-02-10 21:12:14