将数据类型 Clob 转换为 Varchar2 Oracle
Convert datatype Clob to Varchar2 Oracle
我有一个带有 clob 类型列的 Oracle table。我想保留列顺序并将数据类型更改为 varchar2。该列仅包含文本。
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: invalid modification of columns
我试过使该列为空,然后转换为 char 或 long,然后转换为 varchar2。但似乎没有任何效果。我宁愿不必复制 table 来更改一列。
我不只是想阅读内容。我想将列的数据类型从 clob 更改为 varchar2。
将不胜感激。我已经为此工作了一段时间。如果您有任何问题,请告诉我。
您可以删除 CLOB 列,添加 varchar2 列,然后使用 online table redefinition 'fix' 列顺序;假设您使用的是支持该版本的版本,并且您有权使用 DBMS_REDEFINITION
包。带有主键的 table 的非常简单的演示:
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);
如果您确实想保留数据,只需两个额外的步骤,如下面的 rowid 版本所示。
创建一个重新定义 table,其中的列按您想要的顺序排列:
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
文档中有更多关于检查 table 是否对重新定义有效、处理依赖 tables(外键)等的内容
如果您的 table 没有主键,则 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;
您可以执行后续步骤:
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
我有一个带有 clob 类型列的 Oracle table。我想保留列顺序并将数据类型更改为 varchar2。该列仅包含文本。
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: invalid modification of columns
我试过使该列为空,然后转换为 char 或 long,然后转换为 varchar2。但似乎没有任何效果。我宁愿不必复制 table 来更改一列。
我不只是想阅读内容。我想将列的数据类型从 clob 更改为 varchar2。
将不胜感激。我已经为此工作了一段时间。如果您有任何问题,请告诉我。
您可以删除 CLOB 列,添加 varchar2 列,然后使用 online table redefinition 'fix' 列顺序;假设您使用的是支持该版本的版本,并且您有权使用 DBMS_REDEFINITION
包。带有主键的 table 的非常简单的演示:
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);
如果您确实想保留数据,只需两个额外的步骤,如下面的 rowid 版本所示。
创建一个重新定义 table,其中的列按您想要的顺序排列:
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
文档中有更多关于检查 table 是否对重新定义有效、处理依赖 tables(外键)等的内容
如果您的 table 没有主键,则 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;
您可以执行后续步骤:
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