在PL/SQL中,UTL_FILE包提供文本文件輸入和輸出功能。node
能夠訪問的目錄經過初始化參數UTL_FILE_DIR設置。數據庫
注意:UTL_FILE只能讀取服務器端文本文件,不能讀取二進制文件。這時候,應該使用DBMS_LOB包。服務器
使用UTL_FILE包的方法是打開文件文件,執行文件內容寫入和讀取等操做,而後關閉這個文件。若是不關閉這個文件,操做系統會認爲這個文件當前正在使用中,不容許在關閉以前再次寫入這個文件。session
下表列出了UTL_FILE包的主要函數、過程及描述。oracle
下表列出了該報的異常狀況及描述。函數
下面的範例會演示將日期、時間和當前所登錄用戶數寫入日誌文件。spa
如何利用UTL_FILE來寫文件操作系統
1、 設置UTL_FILE_DIR初始化參數日誌
SQL> alter system set utl_file_dir='/home/oracle' scope=spfile;code
重啓數據庫
2、賦予test用戶訪問v$session表的權限
SQL> grant select on v_$session to test;
3、腳本以下
CREATE OR REPLACE PROCEDURE LOG_USER_COUNT (PI_DIRECTORY IN VARCHAR2, PI_FILE_NAME IN VARCHAR2) AS v_file_handle UTL_FILE.FILE_TYPE; v_user_count number; BEGIN SELECT count(*) INTO v_user_count FROM v$session WHERE username is not null; v_file_handle := UTL_FILE.FOPEN(PI_DIRECTORY,PI_FILE_NAME,'W'); UTL_FILE.PUT_LINE(v_file_handle,'--- User log ---'); UTL_FILE.NEW_LINE(v_file_handle);
UTL_FILE.PUT_LINE(v_file_handle,'ON '||TO_CHAR(SYSDATE,'MM/DD/YY HH24:MI'));
UTL_FILE.PUT_LINE(v_file_handle,'Numbers of users logged on: '||v_user_count); UTL_FILE.NEW_LINE(v_file_handle); UTL_FILE.PUT_LINE(v_file_handle,'--- End log ---'); UTL_FILE.NEW_LINE(v_file_handle); UTL_FILE.FCLOSE(v_file_handle); EXCEPTION WHEN UTL_FILE.INVALID_FILENAME THEN DBMS_OUTPUT.PUT_LINE('File is invalid'); WHEN UTL_FILE.WRITE_ERROR THEN DBMS_OUTPUT.PUT_LINE('Oracle is not able to write to file'); END;
4、 執行log_user_count過程
SQL> exec log_user_count('/home/oracle','user.log');
5、查看結果
[oracle@node2 ~]$ cat user.log
--- User log ---
ON 06/25/14 03:02
Numbers of users logged on: 1
--- End log ---
上述範例演示的是如何利用UTL_FILE來寫文件,下面咱們來看看如何利用UTL_FILE來訪問文件,結果基於上例
如何利用UTL_FILE來訪問文件
1、 腳本以下
CREATE OR REPLACE PROCEDURE READ_FILE (PI_DIRECTORY IN VARCHAR2, PI_FILE_NAME IN VARCHAR2) AS v_file_handle UTL_FILE.FILE_TYPE; v_file_line varchar2(1024); BEGIN v_file_handle := UTL_FILE.FOPEN(PI_DIRECTORY,PI_FILE_NAME,'R'); LOOP UTL_FILE.GET_LINE(v_file_handle,v_file_line); DBMS_OUTPUT.PUT_LINE(v_file_line); END LOOP; EXCEPTION WHEN NO_DATA_FOUND THEN UTL_FILE.FCLOSE(v_file_handle); END;
2、 執行read_file過程
SQL> exec read_file('/home/oracle','user.log');
--- User log ---
ON 06/25/14 03:02
Numbers of users logged on: 1
--- End log ---
PL/SQL procedure successfully completed.
附:如何利用UTL_FILE包將表中數據導出到主機文本文件中
CREATE or REPLACE PROCEDURE output AS v_file_handle UTL_FILE.FILE_TYPE; BEGIN v_file_handle := UTL_FILE.FOPEN('TMP','output.txt','W'); UTL_FILE.PUT_LINE(v_file_handle,'EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO');
FOR cur_emp IN(SELECT * FROM emp) LOOP UTL_FILE.PUT_LINE(v_file_handle,cur_emp.empno||' '||cur_emp.ename||' '||cur_emp.job||' '||cur_emp.mgr||' '||cur_emp.hiredate||' '||cur_emp.sal||' '||cur_emp.comm||' '||cur_emp.deptno); END LOOP; UTL_FILE.FCLOSE(v_file_handle); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE||chr(10)||SQLERRM); END;
生成的output.txt內容以下所示:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO 7369 SMITH CLERK 7902 17-DEC-80 800 20 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7566 JONES MANAGER 7839 02-APR-81 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 30 7782 CLARK MANAGER 7839 09-JUN-81 2450 10 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7839 KING PRESIDENT 17-NOV-81 5000 10 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30 7876 ADAMS CLERK 7788 23-MAY-87 1100 20 7900 JAMES CLERK 7698 03-DEC-81 950 30 7902 FORD ANALYST 7566 03-DEC-81 3000 20 7934 MILLER CLERK 7782 23-JAN-82 1300 10 8888 tom SALESMAN 7839 27-AUG-14 1000 0 30