要从SqlServer中把数据导入到Oracle里,SqlServer里表的某个字段为text类型,在使用“SqlServer导入和导出向导”将表导入到Oracle时,该字段如果选Clob的话会出现如下错误:
错误 0xc00470fe: 数据流任务:产品级别对于 组件“数据转换 1”(97)而言不足。 (补充:SqlServer 2005 打了SP1补丁后,Text 到 Clob 的映射可以正常执行)
目前还不清楚这是什么原因引起的,于是就只好使用LONG RAW类型了。完成从SqlServer到Oracle后,又要考虑如何把LONG RAW类型字段的值转存到CLOB类型的字段中。折腾了一番,找到如下方法:
1、先把LONG RAW 转为BLOB,可以用如下Sql语句复制另一个表,并把LONG RAW类型的字段转为BLOB类型的字段;
CREATE TABLE T_SOURCE_1 AS
SELECT ID,TITLE,TO_LOB(CONTENT) AS CONTENT
FROM T_SOURCE
2、把 BLOB 转为 CLOB,在中找到如下一个function,挺实用。
CREATE OR REPLACE FUNCTION blob_to_clob (blob_in IN BLOB) RETURN CLOB
AS
v_clob CLOB;
v_varchar VARCHAR2(32767);
v_start PLS_INTEGER := 1;
v_buffer PLS_INTEGER := 32767;
tmp_num number;
BEGIN
DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);
tmp_num := CEIL(DBMS_LOB.GETLENGTH(blob_in) / v_buffer);
if tmp_num > 0 then --防止传入的BLOB为NULL或长度为0时引发错误
FOR i IN 1..tmp_num
LOOP
v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, v_buffer, v_start));
DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);
v_start := v_start + v_buffer;
END LOOP;
end if;
RETURN v_clob;
END blob_to_clob;
另外DBMS_LOB包中有个procedure叫convertToClob的也是把BLOB转换为CLOB的,但因为是存储过程不适合直接用在sql语句中,使用示例及各个参数的含义如下(来源):
l_blob blob;
l_clob clob := 'x';
l_dest_offsset integer := 1;
l_src_offsset integer := 1;
l_lang_context integer := dbms_lob.default_lang_ctx;
l_warning integer;BEGIN
SELECT bat.data_file INTO l_blob
FROM batches bat WHERE bat.id = p_to_id;
dbms_lob.converttoclob
( dest_lob => l_clob --转换后的CLOB (in out)
, src_blob => l_blob --转换前的BLOB (in)
, amount => dbms_lob.lobmaxsize --(in)
, dest_offset => l_dest_offsset --CLOB开始写入位置 (in out)
, src_offset => l_src_offsset --BLOB开始读取位置 (in out)
, blob_csid => dbms_lob.default_csid --(in)
, lang_context => l_lang_context --与语言相关的东西(in out)
, warning => l_warning --当出错时返回的信息 (out)
);
UPDATE batches SET clob_data = l_clob WHERE id = p_to_id;
END;