oracle存储过程写文件,Oracle写本地文件

oracle存储过程写⽂件,Oracle写本地⽂件Oracle写本地⽂件是指写到运⾏Oracle的主机上,⽽不是运⾏该脚本的机器上。
说起来有点拗⼝,实际上就是⽆论在哪⾥执⾏这个过程,⽣成的⽂件始终都是在服务器上的。
下⾯过程实现了这个功能:
logdir是指⽂件存放路径。有Oracle的directory指定:
create or replace directory log_dir  as '/oracle/admin/orcl';
创建带有clob字段的表:
create table testclob(obj_type varchar2(255), obj_content clob);
插⼊测试数据:
insert into testclob(obj_type, obj_content)
select 'PROCEDURE', _ddl('PROCEDURE', o.object_name)
from dba_objects o
where o.owner = user
and o.object_type = 'PROCEDURE'
创建存储过程:
create or replace procedure sp_writelog2file(logdir varchar2,
filename varchar2,
writemode char := 'W') as
type tbl_result is table of varchar2(2000) index by pls_integer;
v_res tbl_result;
type tbl_clob is table of clob index by pls_integer;
v_clobs  tbl_clob;
v_filename  varchar2(255) := filename;
v_logdir    varchar2(255) := logdir;
v_buffer    pls_integer := 2000;
v_offset    pls_integer := 1;
v_filehandle utl_file.file_type;
function f_readclob(varclob clob)
return tbl_result as
v_maxbuff pls_integer := 2000;
v_cloblen pls_integer := length(varclob);
v_result tbl_result;
v_buffer pls_integer := v_maxbuff;
v_offset pls_integer := 1;
v_nextpos pls_integer := 1;
v_prevpos pls_integer := 1;
v_maxstep pls_integer := 20;
v_nth    pls_integer := v_maxstep;
begin
while v_nextpos <> 0 loop
v_nextpos := dbms_lob.instr(varclob, chr(10), 1, v_nth);
v_buffer  := (case when v_nextpos = 0 then v_cloblen else v_nextpos end) - v_prevpos; if (v_buffer > v_maxbuff and v_nextpos <> 0) then
v_nth := v_nth - 3;/*超过最⼤缓冲区,指针退3个*/
elsif (v_buffer < 3*v_maxbuff/4 and v_nextpos <> 0) then
v_nth := v_nth + 3;/*未达最⼤缓冲区的3/4,指针进3个*/
maxstep
else
ad(varclob, v_buffer, v_offset, v_result(nvl(v_result.last, 0) + 1));
v_prevpos := v_nextpos;
v_nth := v_nth + v_maxstep;
v_offset := v_offset + v_buffer;
end if;
end loop;
return v_result;
end f_readclob;
begin
v_filehandle := utl_file.fopen(v_logdir, v_filename, writemode);
if(utl_file.is_open(v_filehandle)) then
select t2.obj_content
bulk collect into v_clobs
from testclob t2;
for i in 1 .. unt loop
v_res := f_readclob(v_clobs(i));
for j in 1 .. unt loop
utl_file.put_line(v_filehandle, v_res(j));
end loop;
end loop;
end if;
utl_file.fclose(v_filehandle);
exception when others then
utl_file.fclose(v_filehandle);
end sp_writelog2file;
调⽤存储过程,将testclob的内容写到主机上的⽂件中:
call sp_writelog2file('LOG_DIR', '');
对于clob对象的读取,采⽤了分段截取的算法。截取标识为换⾏符(chr(10))。
每次步长为20个换⾏符间隔。假设每次截取长度最⼤值为N(这⾥N=2000)。该间隔区间内,如果字符数范围在[N*3/4, N]之间,则直接截取。
如果⼩于3/4 N长度,则指针标识向前推3个换⾏符间隔。如果⼤于N,则向后退3个换⾏符间隔。保证截取的长度始终在3/4-1个N之间。

本文发布于:2024-09-23 15:30:16,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/350850.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:截取   长度   间隔
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议