加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

oracle用存储过程导出表的clob大字段

(2012-11-06 14:57:22)
标签:

杂谈

分类: ORACLE

要求取出table里的prodid,productid和descriptions2这三个字段的值,其中前两个字段是number类型,最后一个字段是clob类型。

1.创建文件存储目录(实际上Oracle只是关联磁盘目录)
create or replace directory DOCS as '/data1';

2.授予其他用户对目录的访问权限
grant read,write on directory DOCS to scott;

3.导出字段

CREATE OR REPLACE PROCEDURE get_Clob is

  filename varchar2(30);
  l_file UTL_FILE.FILE_TYPE;
  l_buffer VARCHAR2(32767); --缓存区,保证极限大 
  l_amount BINARY_INTEGER:=1000;--每次读取的最大字节数,可自由调节,切忌接近32767 
  l_pos NUMBER:=1;
  l_Blob clob;
  l_Blob_len NUMBER;
  bolb_num NUMBER;
  cursor cur_file is select '"'||prodid||'"' || ',' ||'"'|| productid||'"' || ',' ||'"'|| descriptions2||'"'  from table_name where rownum<=1000;

 

   BEGIN
   l_file:=UTL_FILE.FOPEN('DOCS','zhao.csv','W',32767);

    -- R: 只读模式
    -- A: 追加读写模式
    -- W: 刷新读写模式 

  utl_file.put_line(l_file,'prodid,productid,descriptions2');
  open cur_file;
  LOOP
  FETCH  cur_file into l_Blob;
  EXIT WHEN cur_file%NOTFOUND;


  l_pos:=1;
  bolb_num:=1;
  l_amount:=1000;
  l_Blob_len:=dbms_lob.getlength(l_Blob);
  dbms_output.put_line('.................');
  dbms_output.put_line(l_Blob_len);
  WHILE l_pos
  
  DBMS_LOB.READ(l_Blob,l_amount,l_pos,l_buffer);
  utl_file.put(l_file,l_buffer);
  l_pos:=l_pos+l_amount;
  --bolb_num:=bolb_num+1;
 
  END LOOP;
  utl_file.NEW_LINE(l_file);
  END LOOP;
  UTL_FILE.FCLOSE(l_file);

END get_Clob ;

 

用这种方法只能导出clob字段小于32767的数据,比这大的数据不能导出。看网上说超出32767的数据可以以追加的模式接着写入,于是写成了:

CREATE OR REPLACE PROCEDURE get_Clob  is

  filename varchar2(30);
  l_file UTL_FILE.FILE_TYPE;
  l_buffer VARCHAR2(32767);
  l_buffer2 VARCHAR2(32767);
  l_buffer3 VARCHAR2(32767);
  --l_buffer RAW(32767);
  l_amount BINARY_INTEGER:=1000;
  l_pos NUMBER:=1;
  l_Blob clob;
  l_Blob_len NUMBER;
  bolb_num NUMBER;
  l_count NUMBER:=1;
  --l_prodid NUMBER;
  cursor cur_file is select '"'||prodid||'"' || ',' ||'"'|| productid||'"' || ',' ||'"'|| descriptions2||'"'  from table_name where  rownum<=10000;

 

   BEGIN
   l_file:=UTL_FILE.FOPEN('DOCS','zhao2.csv','W',32767);
   utl_file.put_line(l_file,'prodid,productid,descriptions2');
  open cur_file;
  LOOP
  FETCH  cur_file into l_Blob;
  EXIT WHEN cur_file%NOTFOUND;


  l_pos:=1;
  bolb_num:=1;
  l_amount:=1000;
  l_Blob_len:=dbms_lob.getlength(l_Blob);
  --dbms_output.put_line('.................');
  --dbms_output.put_line(l_Blob_len);
  if l_Blob_len>30000 then
  l_count:=l_count+1;
  dbms_output.put_line('..........'||l_count);
  end if;
  WHILE l_pos
  if bolb_num>30 then    --超过30000的以追加的模式继续输入到文件
  UTL_FILE.FCLOSE(l_file);
  l_file:=UTL_FILE.FOPEN('DOCS','zhao.csv','A',32767);
  DBMS_LOB.READ(l_Blob,l_amount,l_pos,l_buffer);
  utl_file.put(l_file,l_buffer);
 
  end if;
  DBMS_LOB.READ(l_Blob,l_amount,l_pos,l_buffer);
  utl_file.put(l_file,l_buffer);
  l_pos:=l_pos+l_amount;
  bolb_num:=bolb_num+1;
 
  END LOOP;
  utl_file.NEW_LINE(l_file);
  END LOOP;
  UTL_FILE.FCLOSE(l_file);

END get_Clob ;

这种方法可以把超出32767的字段全倒出来,但是超过30000会出现换行,是换行后以追加的模式输入到文件的。这种方法也不是我们想要的。

这个问题一直没有解决,如果哪位看到了这个博文,有好的方法,望回复我。谢谢。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有