oracle中varchar2字段转clob字段,并提供读取方法。

问题描述

CMS系统中有一个表的字段(如:content)是varchar2类型(最多只能存储4000字符),不够用了,因此将其改为clob类型(支持4G存储量)。

如果该字段content列不为空的话,不能直接通过sql语句修改其字段类型,会报ORA-22858的错误,如图所示:

oracle中varchar2字段转clob字段,并提供读取方法。

解决方法:

1.首先创建一个clob的临时字段:

alter table table_name add(tmp clob);

2.然后将content字段内容全部复制到tmp字段中,具体方法请见:

http://my.oschina.net/guyfar/blog/73829

3.修改content字段名为content_bak,将tmp的字段名改为content即可。

alter table table_name rename column content to content_bak;

alter table  table_name  rename column tmp to content;

到这里就完成了字段类型的转换。

虽然数据类型已经转换完成,会发现调用此字段的程序会报错。那是因为通过sql查询出的clob字段是对象类型,因此会报错。

我是通过存储过程来调用的,存储过程如下:

create or replace function getclob(

     table_name  in varchar2,

     field_id     in varchar2,

     field_name  in varchar2,

     v_id  in number,

     v_pos  in number) return varchar2

is

     lobloc  clob;

     buffer  varchar2(32767);

     amount  number := 2000;

     offset  number := 1;

     query_str  varchar2(1000);

begin

   query_str :='select '||field_name||' from '||table_name||' where '||field_id||'= :id ';

--initialize buffer with data to be found

   EXECUTE IMMEDIATE query_str INTO lobloc USING v_id;

   offset:=offset+(v_pos-1)*2000;

--read 2000 varchar2 from the buffer

   dbms_lob.read(lobloc,amount,offset,buffer);

    return buffer;

exception

    when no_data_found then

    return buffer;

end;

调用存储过程的PHP方法:

function edt_disp_getclob($id, $field_id, $field_name, $len) {
	$a = 2000;
	$b = $a / 2;
	if (($len % $b) == 0) {
		$maxpage = floor ( $len / $a );
	} else {
		$maxpage = floor ( $len / $a ) + 1;
	}
	$i = 0;
	$con = "";
	$a = new DB_Sql ();
	while ( $i < $maxpage ) {
		$i = $i + 1;
		$sql = "select getclob('table_name','$field_id','$field_name','$id','$i') as h from dual";
		//echo $sql."<BR>";exit;
		$a->query ( $sql );
		if ($a->next_record ()) {
			$h = $a->Record ["h"];
		}
		$con = $con . $h;
	}
	if (! empty ( $con )) {
		$a->disconnect ();
	}
	return $con;
}

调用:

$con = edt_disp_getclob($id, 'id', 'con', $con_len);

参数说明:

$id :要查询的行

id   :按ID查询

con  :字段名称

$con_len  :要查询的字段长度(提前通过sql查出)

 

至此,所有改动完成。

 

你可能感兴趣的:(oracle,clob,varchar2)