日期:2014-05-16  浏览次数:20526 次

Oracle中long类型表的转换!
Oracle中强烈不推荐用long类型,但是为了解燃眉之急,被迫用了long类型,简单啊,直接insert就行了。不过,没有想到long类型不支持Like,也不能直接to_char。
后悔了,想将long改回varchar2类型,但是又不能直接修改,否则会报错,提醒必须要清空数据,为了不清空数据,综合网上的资料总结了以下解决方案:
表jivemsg中的message类型long需要替换成varchar2:

原jivemsg表结构:
CREATE TABLE "JIVEMSG"
   ( "URI" VARCHAR2(100 BYTE) DEFAULT '' NOT NULL ENABLE,
"SENDER" VARCHAR2(100 BYTE) DEFAULT '',
"RECEIVER" VARCHAR2(100 BYTE) DEFAULT '',
"CREATIONDATE" VARCHAR2(15 BYTE) DEFAULT '',
"MESSAGETYPE" VARCHAR2(100 BYTE) DEFAULT '',
"MESSAGESIZE" NUMBER(*,0) DEFAULT 0,
"MESSAGE" LONG,
"FKDOMAIN" VARCHAR2(20 BYTE) DEFAULT NULL,
"VERSION" VARCHAR2(20 BYTE) DEFAULT NULL,
"FLAGS" VARCHAR2(20 BYTE) DEFAULT NULL,
"RECEIVERNAME" VARCHAR2(50 BYTE) DEFAULT NULL,
"SENDERNAME" VARCHAR2(50 BYTE) DEFAULT NULL,
CONSTRAINT "JIVEMSG_PK" PRIMARY KEY ("URI")
   );

-------------------------------------

转换步骤:

1:创建jivemsg2表:
CREATE TABLE "JIVEMSG2"
   ( "URI" VARCHAR2(100 BYTE) DEFAULT '' NOT NULL ENABLE,
"SENDER" VARCHAR2(100 BYTE) DEFAULT '',
"RECEIVER" VARCHAR2(100 BYTE) DEFAULT '',
"CREATIONDATE" VARCHAR2(15 BYTE) DEFAULT '',
"MESSAGETYPE" VARCHAR2(100 BYTE) DEFAULT '',
"MESSAGESIZE" NUMBER(*,0) DEFAULT 0,
"MESSAGE" LONG,
"FKDOMAIN" VARCHAR2(20 BYTE) DEFAULT NULL,
"VERSION" VARCHAR2(20 BYTE) DEFAULT NULL,
"FLAGS" VARCHAR2(20 BYTE) DEFAULT NULL,
"RECEIVERNAME" VARCHAR2(50 BYTE) DEFAULT NULL,
"SENDERNAME" VARCHAR2(50 BYTE) DEFAULT NULL,
CONSTRAINT "JIVEMSG2_PK" PRIMARY KEY ("URI")
   );
2:修改表jivemsg2的类型
ALTER TABLE JIVEMSG2 MODIFY ("MESSAGE" VARCHAR2(4000 CHAR));

3:将表jivemsg中的数据导入到表jivemsg2中
这步是关键,由于long类型不能直接转换成varchar2。
所以这边用了一个别人写的function来解决。

INSERT INTO JIVEMSG2 select uri,sender,receiver,creationdate,messagetype,messagesize, long_to_char(rowid,'ucstar6','jivemsg','message'),fkdomain,version,flags,receivername,sendername from jivemsg msg;


函数:
/* 其中in_rowid为行id,in_owner为数据库登陆的帐号名,in_table_name为数据库表名,in_column为数据库对应long类型的表字段名称 */
CREATE OR REPLACE FUNCTION LONG_TO_CHAR( in_rowid rowid,in_owner
varchar,in_table_name varchar,in_column varchar2)
RETURN varchar AS
text_c1 varchar2(32767);
sql_cur varchar2(2000);
--
begin
  sql_cur := 'select '||in_column||' from
'||in_owner||'.'||in_table_name||' where rowid =
'||chr(39)||in_rowid||chr(39);
  dbms_output.put_line (sql_cur);
  execute immediate sql_cur into text_c1;

  text_c1 := substr(text_c1, 1, 4000);
  RETURN TEXT_C1; 
END;
/

4:删除表jivemsg,并将jivemsg2更名为jivemsg
DROP TABLE jivemsg;
RENAME JIVEMSG2 TO jivemsg;