2015-02-06 1 views
3

У меня есть таблица с 75 + столбцами в ней. Почти все столбцы имеют ограничение NOT NULL.Oracle: динамически установить все NOT NULL столбцы в таблице, чтобы разрешить NULL

Если сделать гигантский альтер таблицы изменить заявление (с каждой колонкой есть), я получаю ошибку говоря что-то вдоль линий «Вы не можете установить это поле в NULL, потому что уже есть NULL»

Я должен сделать это для нескольких таблиц, и поэтому предпочел бы иметь динамическое решение.

Могу ли я динамически найти все столбцы NOT NULL и установить их в NULL?

Я видел несколько подобных вопросов, подобных этому, но не могу найти решение для Oracle SQL. Modify all columns in a table to 'not null' no matter what

+0

Не знаете, почему вы получите это сообщение, если только вы не пытаетесь изменить столбец на NULLable, который уже является NULLable. Я просто выполнил тест с 4-мя столбцами таблицы, все столбцы NOT NULL и выполнил изменение на всех 4 столбцах до NULL - отлично работает. Можете ли вы опубликовать небольшой рабочий образец, который воссоздает вашу проблему? Держите его в таблице с четырьмя столбцами и четырьмя строками (это будет достаточно большим, чтобы увидеть проблему). Включите создание таблицы, вставку, изменение скриптов. – Ditto

ответ

3

Вот тестовая таблица, с двумя не нулевыми столбцами, и один пустой столбец:

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

4

Вы можете использовать эту процедуру. Вы можете сначала прокомментировать строку, содержащую «выполнить немедленную», чтобы увидеть, что она выполняет, перед запуском. Первый параметр - имя_схемы схемы, второй - имя_таблицы.

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, но я подготовил это решение одновременно и используя процедуру, которую вы избегаете всех этих копий/вклеивания. –

+0

Да, я ленив и никогда не могу вспомнить синтаксис PL/SQL для немедленного выполнения; и мне также нравится видеть, что генерируется, прежде чем оно выполняется. :) –

+0

плюс 1 к вашему и ответ Марка. Спасибо за помощь :) – matrixugly

Смежные вопросы