时utl_file包对于文件读写的控制更加细粒度化,以一种类似于C语言的方式进行文件读写。
从目前看,utl_file生成文件依然是从数据库端生成文件比较成熟的方案,特别是大接口文件。在一些高性能需求的场景下,还是有竞争力的。
对于utl_file包,不能不说到参数utl_file_dir。在Oracle 9.2之前,这个参数是生成读写utl_file执行的最重要参数。
SQL> show parameter utl_file
NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE? ? ? ? VALUE
------------------------------------ ----------- ------------------------------
utl_file_dir? ? ? ? ? ? ? ? ? ? ? ? string? ? ?
在现在我们在网络查询资料时,还是能够看到对utl_file_dir参数的设置要求。在9.2之前的版本中,如果进行文件读写,都需要这个这个参数,将读写文件的所在目录添加到其上。否则Oracle就不能承认这个目录下的文件操作权限。略麻烦的是,这个参数修改要在spfile中进行,生效就需要重启服务器。
这种场景在9.2版本之后有了变化,directory对象的出现,提供了更好的读写目录管理和权限管理。最大的一个好处,就是在代码中,可以不用硬编码方式写目录结构。所以,当前utl_file_dir目录基本不会再使用,只是出于系统兼容性目的。
使用utl_file包方法使用如下步骤:
步骤1:创建directory目录
[oracle@sicslife /]$ su - root
Password:?
--确保操作系统层面的权限!
[root@sicslife ~]# cd /
[root@sicslife /]# chown -R oracle:oinstall /upload/
[root@sicslife /]# ls -l | grep upload
drwxr-xr-x.? 4 oracle oinstall? 4096 Aug? 6 21:21 upload
SQL> create directory utl_path as '/upload';
SQL>
SQL> select directory_name, directory_path from dba_directories;
DIRECTORY_NAME? ? ? ? ? ? ? ? DIRECTORY_PATH
------------------------------ ------------------------------------------------
UTL_PATH? ? ? ? ? ? ? ? ? ? ? /upload
使用directory要解决两个层面权限,一个是操作系统层面,要让Oracle操作系统用户可以使用目录。另一个是directory对象使用权,要进行显示的授权。
SQL> grant write on directory utl_path to scott;
Grant succeeded
SQL> grant execute on utl_file to scott;
Grant succeeded
最后,可以在代码中进行调用。
SQL> set serveroutput on size 1000;
SQL> declare
? 2? ? out_file utl_file.file_type; --文件类型,也就是句柄对象
? 3? ? vc_file_name varchar2(100);
? 4? ? vc_line varchar2(100);
? 5? ? i number;
? 6? begin
? 7? ? vc_file_name := 'utl_file_test.txt';
? 8?
? 9? ? out_file := utl_file.fopen('UTL_PATH',vc_file_name,'w'); --写方式打开文件
?10?
?11? ? if (utl_file.is_open(out_file)) then
?12? ? ? for i in 1..100 loop
?13? ? ? ? ? vc_line := to_char(i)||','||i||'Lines~';
?14? ? ? ? ? utl_file.put_line(out_file,vc_line);
?15? ? ? end loop;
?16? ? else
?17? ? ? dbms_output.put_line('Open Failure~');
?18? ? end if;
?19?
?20? ? utl_file.fclose(out_file); --和C语言一样,需要显示进行关闭
?21? end;
?22? /
PL/SQL procedure successfully completed
最后,就可以在操作系统层面,找到对应文件。
[root@sicslife /]# cd /upload/
[root@sicslife upload]# ls -l
total 12
drwxr-xr-x. 7 oracle oinstall 4096 Aug 27? 2013 database
drwx------. 3 oracle oinstall 4096 Aug? 5 17:26 igb-5.3.2
-rw-r--r--. 1 oracle oinstall 1184 Aug? 7 02:19 utl_file_test.txt
[root@sicslife upload]# cat utl_file_test.txt?
1,1Lines~
2,2Lines~
3,3Lines~
4,4Lines~
5,5Lines~
6,6Lines~
(篇幅原因,有省略…….)
?[root@sicslife upload]#
Utl_file包是一种比较成熟的文件读写方案,除了实例中操作的步骤方法之外,还定义了很多有用的读写方法、异常类型,这对于我们进行完善编程是很有意义的。同时,在实际应用中,utl_file有着更多的细节因素和限制特性,本篇不予累述。
3、结论
利用数据库生成文件,是非常常见的需求。在不借助第三方工具的情况下,spool和utl_file是不错的工具选择。