PL/SQL-- UTL FILE包的使用介紹
在PL/SQL中,UTL_FILE包提供了文字檔案輸入和輸出互功能。也就是說我們可以通過該包實現從作業系統級別來實現檔案讀取輸入或者是寫入到作業系統檔案。通過該包也可以將其他系統的資料載入到資料庫中。如載入web伺服器日誌,使用者登入資料庫日誌乃至Oracle日誌檔案等等。本文主要描述了UTL_FILE的功能以及通過例項演示並理解這個包下相關過程函式的用法。
1、UTL_FILE介紹
a、實現基於作業系統級別的讀取與寫入功能
b、該方式為基於伺服器端的文字檔案訪問模式,不支援二進位制檔案
c、可以通過設定引數utl_file_dir來設定pl/sql訪問作業系統檔案的多個路徑
d、所有使用者可以讀寫utl_file_dir引數設定的目錄,因此應考慮安全問題
e、也可以將引數utl_file_dir置空,而通過建立directory以及授予對directory許可權來進行訪問os檔案(推薦方式)
2、UTL_FILE包中的過程和函式
a、UTL_FILE中定義的file_type為記錄型別,如下所示其成員是私有的,不能夠被直接引用或改變這個記錄的元件。
TYPE file_type IS RECORD (
id BINARY_INTEGER,
datatype BINARY_INTEGER,
byte_mode BOOLEAN);
b、UTL_FILE中相關過程函式的功能說明
FCLOSE Procedure Closes a file
FCLOSE_ALL Procedure Closes all open file handles
FCOPY Procedure Copies a contiguous portion of a file to a newly created file
FFLUSH Procedure Physically writes all pending output to a file
FGETATTR Procedure Reads and returns the attributes of a disk file
FGETPOS Function Returns the current relative offset position within a file, in bytes
FOPEN Function Opens a file for input or output
FOPEN_NCHAR Function Opens a file in Unicode for input or output
FREMOVE Procedure Deletes a disk file, assuming that you have sufficient privileges
FRENAME Procedure Renames an existing file to a new name, similar to the UNIX mv function
FSEEK Procedure Adjusts the file pointer forward or backward within the file by the number of bytes specified
GET_LINE Procedure Reads text from an open file
GET_LINE_NCHAR Procedure Reads text in Unicode from an open file
GET_RAW Procedure Reads a RAW string value from a file and adjusts the file pointer ahead by the number of bytes read
IS_OPEN Function Determines if a file handle refers to an open file
NEW_LINE Procedure Writes one or more operating system-specific line terminators to a file
PUT Procedure Writes a string to a file
PUT_LINE Procedure Writes a line to a file, and so appends an operating system-specific line terminator
PUT_LINE_NCHAR Procedure Writes a Unicode line to a file
PUT_NCHAR Procedure Writes a Unicode string to a file
PUTF Procedure A PUT procedure with formatting
PUTF_NCHAR Procedure A PUT_NCHAR procedure with formatting, and writes a Unicode string to a file, with formatting
PUT_RAW Procedure Accepts as input a RAW data value and writes the value to the output buffer
3、演示ULT_FILE用法
a、使用UTL_FILE的主要步驟(使用directory方式) --先建立用於存放os檔案的目錄 [email protected]> ho mkdir -p /u03/database/usbo/db_utl_dir --在資料庫層面新增directory [email protected]> create directory db_utl_dir as '/u03/database/usbo/db_utl_dir'; --許可權授予 [email protected]> grant read,write on directory db_utl_dir to public;b、從SQL查詢寫入到資料檔案 DECLARE vsfile UTL_FILE.file_type; --->定義用於接收檔案控制代碼的型別 v_cnt PLS_INTEGER := 0; BEGIN vsfile := UTL_FILE.fopen ('DB_UTL_DIR', --->使用fopen開啟檔案,定義了檔案路徑,檔名,讀寫方式以及每一行字元的最大長度,預設為1024 'emp.txt', 'W', 200); FOR i IN (SELECT t.ename || ',' || t.job AS msg --->使用了一個for迴圈來讀取scott.emp表 FROM scott.emp t WHERE t.sal>2000) LOOP UTL_FILE.put_line (vsfile, i.msg); --->將for迴圈查詢的內容使用put_line寫入到檔案 v_cnt := v_cnt + 1; --->計數器,用於統計寫入的記錄數 END LOOP; UTL_FILE.fflush (vsfile); UTL_FILE.fclose (vsfile); DBMS_OUTPUT.put_line (v_cnt || ' rows unloaded'); END; / 6 rows unloaded PL/SQL procedure successfully completed. --檢視產生的檔案 [email protected]> ho more /u03/database/usbo/db_utl_dir/emp.txt JONES,MANAGER BLAKE,MANAGER CLARK,MANAGER SCOTT,ANALYST KING,PRESIDENT FORD,ANALYSTc、從資料檔案讀入並寫入到表 [email protected]> create table tb_emp(val varchar2(30), file_name varchar2(10)); [email protected]> exec read_demo('emp.txt','db_utl_dir'); -->呼叫過程來實現,程式碼見文章尾部 PL/SQL procedure successfully completed. [email protected]> select * from tb_emp; VAL FILE_NAME ----------------------------- --------------------- JONES,MANAGER emp.txt BLAKE,MANAGER emp.txt CLARK,MANAGER emp.txt SCOTT,ANALYST emp.txt KING,PRESIDENT emp.txt FORD,ANALYST emp.txt 6 rows selected.d、讀寫混合模式示例 [email protected]> set serveroutput on; [email protected]> exec rw_demo; -->呼叫過程來實現,程式碼見文章尾部 14 14 28 42 56 71 84 PL/SQL procedure successfully completed. [email protected]> ho ls out.txt x.txt [email protected]> ho more out.txt JONES,MANAGER JONES,MANAGER BLAKE,MANAGER CLARK,MANAGER SCOTT,ANALYST KING,PRESIDENT FORD,ANALYSTe、演示中用到的過程 --下面是讀模式的過程程式碼 CREATE OR REPLACE PROCEDURE read_demo (file_name_in VARCHAR2, utl_dir_in VARCHAR2) --兩個傳入引數,一個用於指定檔名,一個用於指定utl_file_dir目錄 --Author : Leshami --Blog : http://blog.csdn.net/leshami IS vsfile UTL_FILE.file_type; vnewline VARCHAR2 (200); v_utl_dir VARCHAR2 (30); BEGIN v_utl_dir := UPPER (utl_dir_in); vsfile := UTL_FILE.fopen (v_utl_dir, file_name_in, 'r'); --->開啟檔案 IF UTL_FILE.is_open (vsfile) THEN LOOP BEGIN UTL_FILE.get_line (vsfile, vnewline); -->從檔案讀入行 IF vnewline IS NULL THEN EXIT; END IF; INSERT INTO tb_emp (val, file_name) --->將讀入的行插入到表 VALUES (vnewline, file_name_in); EXCEPTION WHEN NO_DATA_FOUND THEN EXIT; END; END LOOP; COMMIT; END IF; UTL_FILE.fclose (vsfile); --->關閉開啟的檔案 UTL_FILE.frename (v_utl_dir, --->此處進行了重新命名 file_name_in, v_utl_dir, 'x.txt', TRUE); EXCEPTION --->定義了相關的異常資訊 WHEN UTL_FILE.invalid_mode THEN raise_application_error (-20051, 'Invalid Mode Parameter'); WHEN UTL_FILE.invalid_path THEN raise_application_error (-20052, 'Invalid File Location'); WHEN UTL_FILE.invalid_filehandle THEN raise_application_error (-20053, 'Invalid Filehandle'); WHEN UTL_FILE.invalid_operation THEN raise_application_error (-20054, 'Invalid Operation'); WHEN UTL_FILE.read_error THEN raise_application_error (-20055, 'Read Error'); WHEN UTL_FILE.internal_error THEN raise_application_error (-20057, 'Internal Error'); WHEN UTL_FILE.charsetmismatch THEN raise_application_error (-20058, 'Opened With FOPEN_NCHAR But Later I/O Inconsistent'); WHEN UTL_FILE.file_open THEN raise_application_error (-20059, 'File Already Opened'); WHEN UTL_FILE.invalid_maxlinesize THEN raise_application_error (-20060, 'Line Size Exceeds 32K'); WHEN UTL_FILE.invalid_filename THEN raise_application_error (-20061, 'Invalid File Name'); WHEN UTL_FILE.access_denied THEN raise_application_error (-20062, 'File Access Denied By'); WHEN UTL_FILE.invalid_offset THEN raise_application_error (-20063, 'FSEEK Param Less Than 0'); WHEN OTHERS THEN raise_application_error (-20099, 'Unknown UTL_FILE Error'); END read_demo; / --下面是讀寫模式過程的程式碼,這個過程實現了從一個數據檔案讀出並寫入到另外一個數據檔案 CREATE OR REPLACE PROCEDURE rw_demo IS infile UTL_FILE.file_type; outfile UTL_FILE.file_type; vnewline VARCHAR2 (4000); i PLS_INTEGER; j PLS_INTEGER := 0; seekflag BOOLEAN := TRUE; BEGIN -- open a file to read infile := UTL_FILE.fopen ('DB_UTL_DIR', 'x.txt', 'r'); -->開啟原始檔用於讀取資料 -- open a file to write outfile := UTL_FILE.fopen ('DB_UTL_DIR', 'out.txt', 'w'); -->建立目標檔案用於存放資料 -- if the file to read was successfully opened IF UTL_FILE.is_open (infile) THEN -- loop through each line in the file LOOP BEGIN UTL_FILE.get_line (infile, vnewline); -->從原始檔讀取行 i := UTL_FILE.fgetpos (infile); -->將行的位置賦值並輸出 DBMS_OUTPUT.put_line (TO_CHAR (i)); UTL_FILE.put_line (outfile, vnewline, FALSE); -->將得到的資料行寫出到檔案控制代碼緩衝 UTL_FILE.fflush (outfile); -->將資料行從緩衝區寫入到檔案 IF seekflag = TRUE THEN UTL_FILE.fseek (infile, NULL, -30); -->用於調整檔案指標,即偏移量 seekflag := FALSE; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN EXIT; END; END LOOP; COMMIT; END IF; UTL_FILE.fclose (infile); -->關閉原始檔 UTL_FILE.fclose (outfile); -->關閉目標檔案 EXCEPTION WHEN OTHERS THEN raise_application_error (-20099, 'Unknown UTL_FILE Error'); END rw_demo; / 注意在使用UTL_FILE包用到DIRECTORY資料庫物件時,名字一定要大寫,否則會遭遇“ORA-29280: invalid directory path”錯誤主要參考: http://psoug.org/reference/utl_file.html http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/u_file.htm#BABGGEDF
更多參考