Как изменить тип данных столбца если таблица заполнена и используется?
Есть столбец ID с числовыми значениями. При создании таблицы, в следствии ошибки проектирования, он был объявлен как VARCHAR.
С этим столбцом постоянно возникают проблемы, например, сравнение значений столбца может привести к неожидаемым результатам:
select to_number (max (id)) maxid from (
select '9' id from dual union all
select '10' from dual);
MAXID
----------
9
Есть решение - изменить тип данных столбца:
alter table table1 modify id number(10,0);
, но оно выдает ошибку:
ORA-01439: column to be modified must be empty to change datatype
Какой наилучший метод решения этой проблемы?
Ответы (1 шт):
Можно реорганизовать таблицу во время её использования с помощью PL/SQL пакета DBMS_REDEFINITION.
Воспроизводимый пример:
create table t1 (
id varchar2 (10) primary key);
create table t2 (
id number(10,0) primary key);
insert into t1
select '9' from dual union all
select '10' from dual;
commit;
begin
dbms_redefinition.start_redef_table (
uname=>user, orig_table=>'t1',
int_table=>'t2',
col_mapping => 'to_number (id) id',
options_flag => dbms_redefinition.cons_use_rowid);
end;
/
exec dbms_redefinition.sync_interim_table (user, 't1', 't2');
При завершении реорганизации, таблица t1 будет кратковременно заблокирована, а затем она полностью соответствует по структуре таблице t2, и последняя может быть удалена:
exec dbms_redefinition.finish_redef_table (user, 't1', 't2');
desc t1
Name Null? Type
---- -------- ----------
ID NOT NULL NUMBER(10)
select max (id) maxid from t1;
MAXID
----------
10
drop table t2 cascade constraints purge;