2015-05-26 5 views
0

У меня есть таблица Oracle с столбцом типа clob. Я хочу сохранить порядок столбцов и изменить тип данных на varchar2. В столбце содержится только текст.Преобразование типа данных Clob to Varchar2 Oracle

update IN_MSG_BOARD set MSG_TEXT = null; 
alter table IN_MSG_BOARD modify MSG_TEXT long; 
alter table IN_MSG_BOARD modify MSG_TEXT varchar2(4000); 

Я получаю стандартное сообщение:

ORA-22859: неправильное изменение столбцов

Я попытался сделать столбец нулевой, а затем преобразовать в уголь или длинные, затем к varchar2. Но ничего не работает. Я бы предпочел не копировать таблицу, чтобы изменить один столбец.

Я не просто хочу прочитать содержание. Я хочу изменить тип данных столбца из clob в varchar2.

Справка была бы принята с благодарностью. Я работал над этим некоторое время. Дайте знать, если у вас появятся вопросы.

+0

Вы рискуете, что, преобразуя данные, вы усекаете любые строки длиной более 4000 символов. Вы уверены, что все ваши данные составляют менее 4000 символов? – kevinsky

+0

Порядок столбцов не имеет большого значения. Есть ли причина, по которой вам нужно ее сохранить? –

+0

возможно [дубликат] (http://stackoverflow.com/questions/5731301/clob-vs-varchar2-and-are-there-other-alternatives) – tbone

ответ

0

Вы можете удалить столбец CLOB, добавить столбец varchar2 и затем исправить порядок столбцов с помощью online table redefinition; если вы используете версию, которая поддерживает это, и у вас есть разрешение на использование пакета DBMS_REDEFINITION. Очень простой демонстрационный для таблицы с первичным ключом:

create table in_msg_board(col1 number primary key, msg_text clob, col3 date); 

Если вы не хотите, чтобы сохранить данные в исходной колонке:

alter table IN_MSG_BOARD drop column msg_text; 
alter table IN_MSG_BOARD add msg_text varchar2(4000); 

Если вы хотите сохранить данные, которые он только два дополнительных шага, показанных в следующей версии.

Создать таблицу переопределение, с столбцы в порядке, вы хотите:

create table in_msg_board_redef(col1 number, msg_text varchar2(4000), col3 date); 

И позвони пакет:

BEGIN 
    DBMS_REDEFINITION.START_REDEF_TABLE(
    uname => user, 
    orig_table => 'IN_MSG_BOARD', 
    int_table => 'IN_MSG_BOARD_REDEF', 
    col_mapping => 'col1 col1, msg_text msg_text, col3 col3'); 
    DBMS_REDEFINITION.FINISH_REDEF_TABLE(uname => user, 
    orig_table => 'IN_MSG_BOARD', 
    int_table => 'IN_MSG_BOARD_REDEF'); 
END; 
/

desc in_msg_board; 

Name  Null Type   
-------- ---- -------------- 
COL1   NUMBER   
MSG_TEXT  VARCHAR2(4000) 
COL3   DATE   

Там более в документации о проверке таблицы действителен для переопределение, обработка зависимых таблиц (внешние ключи) и т. д.


Если ваш стол не имеет первичного ключа, а затем you can use rowids, передав дополнительный флаг опции. Для этой демонстрации я тоже сохраню данные.

create table in_msg_board(col1 number, msg_text clob, col3 date); 
insert into in_msg_board values (1, 'This is a test', sysdate); 
alter table IN_MSG_BOARD add msg_text_new varchar2(4000); 
update IN_MSG_BOARD set msg_text_new = dbms_lob.substr(msg_text, 4000, 1); 
alter table IN_MSG_BOARD drop column msg_text; 
alter table IN_MSG_BOARD rename column msg_text_new to msg_text; 

desc in_msg_board 

Name  Null Type   
-------- ---- -------------- 
COL1   NUMBER   
COL3   DATE   
MSG_TEXT  VARCHAR2(4000) 

Как и прежде, в этот момент новый столбец (содержащий данные на этот раз) есть, но находится в неправильном положении.Так заново, как и раньше, но с DBMS_REDEFINITION.CONS_USE_ROWID флагом:

create table in_msg_board_redef(col1 number, msg_text varchar2(4000), col3 date); 

BEGIN 
    DBMS_REDEFINITION.START_REDEF_TABLE(
    uname => user, 
    orig_table => 'IN_MSG_BOARD', 
    int_table => 'IN_MSG_BOARD_REDEF', 
    col_mapping => 'col1 col1, msg_text msg_text, col3 col3', 
    options_flag => DBMS_REDEFINITION.CONS_USE_ROWID); 
    DBMS_REDEFINITION.FINISH_REDEF_TABLE(uname => user, 
    orig_table => 'IN_MSG_BOARD', 
    int_table => 'IN_MSG_BOARD_REDEF'); 
END; 
/

desc in_msg_board; 

Name  Null Type   
-------- ---- -------------- 
COL1   NUMBER   
MSG_TEXT  VARCHAR2(4000) 
COL3   DATE   

и данные там тоже:

select * from in_msg_board; 

     COL1 MSG_TEXT    COL3  
---------- -------------------- --------- 
     1 This is a test  27-MAY-15 

И как уже упоминалось в связанной документации, вы можете затем удалить скрытый столбец, используемый для управления в * ROWID'ы:

alter table in_msg_board drop unused columns; 
+0

Спасибо за всю информацию. Сейчас я читаю документацию. – brandonbanks

+0

Таким образом, моя таблица не имеет первичного ключа. Вы сказали, что это требование использовать переопределение онлайн-таблицы? – brandonbanks

+0

@bbanks - ну, это проще; [Есть также метод rowid] (http://docs.oracle.com/cd/E11882_01/server.112/e25494/tables.htm#ADMIN11668), но я этого не использовал. Демо было для версии ПК. –

0

Вы можете сделать следующие шаги:

1. alter table my_table add (new_column varchar2(4000)); 

2. update my_table set new_column = dbms_lob.substr(old_column,4000,1); 

3. alter table my_table drop column old_column 
+0

Вам также нужно будет переименовать новый столбец; Я показал это тоже в своем ответе * 8-) Но это не относится к требованию сохранения порядка столбцов. –

+0

Спасибо за помощь Ибрагима. Но, как сказал Алекс, это не поддерживает порядок столбцов. – brandonbanks

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