【收藏】Oracle存储过程读写文件

本文介绍如何使用Oracle存储过程实现文件与数据库表之间的数据交互。包括创建目录、注册路径及编写存储过程来导出表数据到文件和从文件导入数据到表的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近有朋友问我用Oricle存储过程读写文件,我说应该没有问题,然后本人用Google搜索一篇好文章,故收藏之!
测试环境:Oracle 9i +Linux for SUSE

有时候我们需要在文件与数据库表之间利用程序来实现两者的交互,这里可以利用UTL_FILE包实现对文件的I/O操作.下面就分别介绍文件写表以及表数据写文件.

[1]表信息导出到文件

在SUSE上建议一个文件夹/home/zxin10/file,然后对其chmod g+w file进行授权(否则无法导出到文件),再对您指定的路径(/home/zxin10/file)向Oracle的系统表sys.dir$进行注册(否则也是无法成功将信息导出到文件),操作完后可以查询sys.dir$可以看到表中的OS_PATH中有您指定的路径位置.

注册方式:执行SQL语句create or replace directory BBB as '/home/zxin10/file'; 即可

存储过程如下:( 写文件时,文件名可以不用先创建,程序中会自动创建指定文件)

None.gif CREATE   OR   REPLACE   PROCEDURE  V3_SUB_FETCH_TEST_2
None.gif(
None.gif   V_TEMP 
VARCHAR2 ,
None.gif   
-- 1为成功,0为失败
None.gif
   v_retvalue   OUT  NUMBER  
None.gif )
None.gif
AS
None.gif  
-- 游标定义
None.gif
  type ref_cursor_type  is  REF  CURSOR ;
None.gif  cursor_select   ref_cursor_type;
None.gif  select_cname    
varchar2 ( 1000 );
None.gif  
None.gif  v_file_handle   utl_file.file_type;
None.gif  
None.gif  v_sql 
varchar2 ( 1000 );
None.gif  v_filepath 
Varchar2 ( 500 );
None.gif  v_filename 
Varchar2 ( 500 );
None.gif  
-- 缓冲区
None.gif
  v_results  Varchar2 ( 500 );
None.gif  
None.gif  v_pid 
varchar2 ( 1000 );
None.gif  v_cpcnshortname 
Varchar2 ( 500 );
None.gif 
None.gif  
begin
None.gif      v_filepath :
=  V_TEMP;
None.gif      
if  v_filepath  is   null   then
None.gif         v_filepath :
=   ' /home/zxin10/file3 ' ;
None.gif      
end   if ;
None.gif      v_filename:
= ' free_ ' ||  substr(to_char(sysdate, ' YYYYMMDDHH24MI ' ), 1 , 10 || ' .all '  ;
None.gif      
-- 游标开始
None.gif
      select_cname: = ' select cpid,cpcnshortname from zxdbm_ismp.scp_basic '
None.gif      
-- 打开一个文件句柄 ,同时fopen的第一个参数必须是大写   
None.gif
      v_file_handle: = utl_file.fopen( ' BBB ' ,v_filename, ' A ' );
None.gif      
Open  cursor_select  For  select_cname;   
None.gif      
Fetch   cursor_select  into  v_pid,v_cpcnshortname;
None.gif      
While   cursor_select % Found   
None.gif      Loop
None.gif      v_results :
=  v_pid || ' | ' || v_cpcnshortname;
None.gif      
-- 将v_results写入文件
None.gif
      utl_file.put_line(v_file_handle,v_results);   
None.gif      
Fetch   cursor_select  into  v_pid,v_cpcnshortname;      
None.gif      
End  Loop;
None.gif      
None.gif      
Close  cursor_select; -- 关闭游标
None.gif
      utl_file.fClose(v_file_handle); -- 关闭句柄
None.gif
      v_retvalue : = 1 ;
None.gif  exception 
when  others  then
None.gif         v_retvalue :
= 0
None.gif  
end  V3_SUB_FETCH_TEST_2;
None.gif




[2]将文件信息导入到表中

和上面一样,先对指定文件路径进行chmod,然后想Oracle的sys.dir$进行路径注册.

文件zte.apsuic位于/home/zxin10/file下,其数据格式:
1|22|cheng
2|33|zhou
3|44|heng
4|55|yaya


表LOADDATA脚本:

None.gif --  Create table
None.gif
create   table  LOADDATA
None.gif(
None.gif  ID   
VARCHAR2 ( 50 ),
None.gif  AGE  
VARCHAR2 ( 50 ),
None.gif  NAME 
VARCHAR2 ( 50 )
None.gif)
    /None.gif



程序如下:(读取文件时,指定文件名一定要预先存在,否则程序会失败)

None.gif create   or   replace  directory BBB  as   ' /home/zxin10/file ' ;
None.gif
/
None.gif
-- 作用法是将特定的文件路径信息想Oracle注册(注册信息存放在sys.dir$表中)
None.gif

None.gif
CREATE   OR   REPLACE   PROCEDURE  V3_SUB_FETCH_TEST_3
None.gif(
None.gif   
-- 文件中的信息导入表中
None.gif
     V_TEMP  VARCHAR2 ,
None.gif     v_retvalue   OUT 
NUMBER   -- 1 成功 ,0失败
None.gif
AS  
None.gif  v_file_handle   utl_file.file_type;  
None.gif  v_sql 
varchar2 ( 1000 );
None.gif  v_filepath 
Varchar2 ( 500 );
None.gif  v_filename 
Varchar2 ( 500 );  
None.gif  
-- 文件到表字段的映射
None.gif
  v_id  varchar2 ( 1000 );
None.gif  v_age 
varchar2 ( 1000 );
None.gif  v_name 
varchar2 ( 1000 );
None.gif  
-- 缓冲区
None.gif
  v_str  varchar2 ( 1000 );
None.gif  
-- 列指针
None.gif
  v_i  number ;
None.gif  
-- 字符串定位解析指针
None.gif
  v_sposition1  number ;
None.gif  v_sposition2 
number ;
None.gif  
begin
None.gif      v_filepath :
=  V_TEMP;
None.gif      
if  v_filepath  is   null   then
None.gif         v_filepath :
=   ' /home/zxin10/file ' ;
None.gif      
end   if ;
None.gif      v_filename:
= ' zte.apsuic ' ;
None.gif      
-- v_sql:= 'create or replace directory CCC as '''|| v_filepath || '''';
None.gif
       -- execute immediate v_sql; 
None.gif
      
None.gif      v_file_handle:
= utl_file.fopen( ' CCC ' ,v_filename, ' r ' );       
None.gif      Loop
None.gif             
-- 将文件信息读取到缓冲区v_str中,每次读取一行
None.gif
             utl_file.get_line(v_file_handle,v_str);
None.gif             
-- dbms_output.put_line(v_str); 
None.gif
              -- 针对每行的列数
None.gif
             v_i : =   1 ;
None.gif             
-- 针对字符串每次的移动指针
None.gif
             v_sposition1 : =   1 ;
None.gif             
-- 文件中每行信息3列,循环3次
None.gif
              FOR  I  IN   1 .. 3  loop               
None.gif             
-- 当instr(v_str, '|', 6)其中v_str为1|22|wuzhuocheng ,它返回0
None.gif
             v_sposition2 : =  instr(v_str,  ' | ' , v_sposition1);
None.gif             
-- 字符串解析正常情况
None.gif
              if  v_sposition2  <>   0   then
None.gif               
if  v_i = 1       then
None.gif                  v_id :
=  substr(v_str, v_sposition1, v_sposition2  -  v_sposition1);       -- 第一列               
None.gif
               elsif  v_i = 2   then
None.gif                    v_age :
=  substr(v_str, v_sposition1, v_sposition2  -  v_sposition1);  -- 第二列
None.gif
               elsif v_i = 3    then
None.gif                  v_name :
=  substr(v_str, v_sposition1, v_sposition2  -  v_sposition1);     -- 第三列 
None.gif
                else
None.gif                  
return ;
None.gif               
end   if ;                            
None.gif             
-- 字符串解析异常情况
None.gif
              else  
None.gif               
if  v_i = 1      then
None.gif                v_id :
=  substr(v_str, v_sposition1);       -- 第一列
None.gif
               elsif v_i = 2   then
None.gif                  v_age :
=  substr(v_str, v_sposition1);  -- 第二列
None.gif
               elsif v_i = 3   then
None.gif                v_name :
=  substr(v_str, v_sposition1);     -- 第三列 
None.gif
                else
None.gif                
return ;
None.gif               
end   if ;  
None.gif             
end   if ;   
None.gif             v_sposition1 :
=  v_sposition2  +   1 ;
None.gif             v_i :
=  v_i + 1 ;
None.gif             
end  loop; 
None.gif             
-- 每列循环完后将信息insert into表中
None.gif
              insert   into  zxdbm_ismp.loaddata  values (v_id,v_age,v_name);                  
None.gif      
End  Loop;
None.gif      
-- 关闭句柄
None.gif
      utl_file.fClose(v_file_handle);
None.gif      v_retvalue :
= 1 ;
None.gif  exception 
when  others  then
None.gif         v_retvalue :
= 0
None.gif  
end  V3_SUB_FETCH_TEST_3;

文章出处:http://www.blogjava.net/cheneyfree/archive/2007/12/04/165275.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值