在Oracle数据库中,utl_file包能够让我们在PL/SQL里直接读写数据库服务器上的文件,常用于数据导出、日志生成和配置文件读取。掌握它需要理解目录对象、文件打开模式以及标准的读写流程。

一、创建目录对象并授权
Oracle不能直接访问操作系统绝对路径,必须通过目录对象(directory)映射。需要用管理员账号先创建目录并给用户授权。
-- 用sys或system登录执行 CREATE OR REPLACE DIRECTORY file_dir AS '/tmp/oracle_files'; GRANT READ, WRITE ON DIRECTORY file_dir TO scott;
二、使用utl_file写文件
下面例子在scott用户下,将emp表部分数据写出到服务器文件emp_data.txt中。
DECLARE
v_file UTL_FILE.FILE_TYPE; -- 文件句柄
v_line VARCHAR2(200);
CURSOR c_emp IS
SELECT ename, sal FROM emp WHERE ROWNUM <= 5;
BEGIN
-- 以写模式打开文件,路径用目录对象名
v_file := UTL_FILE.FOPEN('FILE_DIR', 'emp_data.txt', 'W');
FOR r IN c_emp LOOP
v_line := r.ename || ',' || r.sal;
UTL_FILE.PUT_LINE(v_file, v_line); -- 写一行
END LOOP;
UTL_FILE.FCLOSE(v_file); -- 关闭文件
EXCEPTION
WHEN OTHERS THEN
IF UTL_FILE.IS_OPEN(v_file) THEN
UTL_FILE.FCLOSE(v_file);
END IF;
RAISE;
END;
/
三、使用utl_file读文件
读取刚才生成的文件,并将内容打印到输出。
DECLARE
v_file UTL_FILE.FILE_TYPE;
v_line VARCHAR2(200);
BEGIN
v_file := UTL_FILE.FOPEN('FILE_DIR', 'emp_data.txt', 'R');
LOOP
BEGIN
UTL_FILE.GET_LINE(v_file, v_line); -- 读一行
DBMS_OUTPUT.PUT_LINE(v_line);
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT; -- 读到文件末尾退出
END;
END LOOP;
UTL_FILE.FCLOSE(v_file);
END;
/
四、常见模式与注意点
- W:写模式,文件不存在则新建,存在则覆盖
- A:追加模式,在文件末尾添加内容
- R:读模式,文件必须存在
- 目录对象名在fopen中必须大写,否则可能报找不到路径
- 文件位于数据库服务器,不是客户端机器
五、权限错误排查
| 错误现象 | 可能原因 |
|---|---|
| ORA-29280: invalid directory path | 目录对象名写错或未授权 |
| ORA-06512: at UTL_FILE | 操作系统目录不存在或Oracle进程无权限 |
通过上述实例可以看到,utl_file包的读写操作并不复杂,关键是目录对象配置正确并且捕获异常安全关闭文件。熟练后便可将其用于定时导出或接口文件处理等场景。