On more than fewer occasions, while developing PL/SQL programs, we are required to read / write data from text files that reside on our operating systems. UTL_FILE package lets us to read / write files from our PL/SQL programs.
In this post, I shall try to explain some of the procedures that are primarily used during this process and a sample code is provided at the end of the post. The objective of the sample code would be “read” the data from a csv file and then to “write” data into another file placed on the server.
Some of the primary procedures used to read and write using UTL_FILE are:
UTL_FILE.fgetattr: This procedure is used to check if the file exists or not in the specified directory location. It also returns the attributes (properties) of a file.
UTL_FILE.FGETATTR(location IN VARCHAR2,
filename IN VARCHAR2,
fexists OUT BOOLEAN,
file_length OUT NUMBER,
block_size OUT BINARY_INTEGER);
The input and output parameters are:
- location: Directory location of the source file,
ALL_DIRECTORIESview (case sensitive).
- filename: Name of the file to be processed.
- fexists: The procedure returns TRUE value if the file exists in the directory.
- file_length: Length of the file in bytes.
- block_size: File system block size in bytes.
UTL_FILE.fopen: This function opens the file that needs to be processed (read or write).
location IN VARCHAR2,
filename IN VARCHAR2,
open_mode IN VARCHAR2,
max_linesize IN BINARY_INTEGER DEFAULT 1024)
The input parameters are:
- location: Directory location of file. This string is a directory object name and must be specified in upper case.
- filename: File name, including extension (file type), without directory path. If a directory path is given as a part of the filename, it is ignored by
- open_mode: The mode in which the file has to be opened in. The mostly used attributes are: r -> read and w -> write.
- UTL_FILE.get_line: Once the file is opened, the get_line procedure reads the text from the open file places the text in the output buffer parameter. If the len parameter is null – then the oracle provides the max_linesize value to that parameter.
file IN FILE_TYPE,
buffer OUT VARCHAR2,
len IN PLS_INTEGER DEFAULT NULL);
The parameters are:
- file: Active file handle returned by an FOPEN call.
- buffer: Data buffer to receive the line read from the file.
- UTL_FILE.put_line: The put_line procedure writes the text string stored in the buffer parameter to the open file identified by file handle.
file IN FILE_TYPE,
buffer IN VARCHAR2,
autoflush IN BOOLEAN DEFAULT FALSE);
The parameters are:
- file: The file that is being processed and is called using the active file handle.
- buffer: Text buffer that contains the text lines that need to be written to the file.
- UTL_FILE.fclose: This fclose procedure closes the file that is opened earlier. This is a mandatory statement during the UTL_File process. Not closing the file would keep the file open and make it unable to move or delete the file at a later stage.
The Input read file – Test_UTL_Read_File.csv has the following content:
In order to explain UTL_FILE, below is the sample code that uses some of the procedures explained above. The objective of this code is to:
- Check to see if the file exists.
- Open the file.
- Read the data from the file line by line.
- Write the data into another file on the same server.
- Close the file.
l_file_exists BOOLEAN := FALSE;
l_dir CONSTANT VARCHAR2 (100) DEFAULT 'XXCMNDIR';
l_new_line VARCHAR2 (500);
l_delim VARCHAR2 (1) := ',';
l_var1 VARCHAR2 (1000) := 'INSERT INTO XX_TEST_UTL_TBL (ID, STUDENT_NUM, SUBJECT) VALUES (';
l_var2 VARCHAR2 (1) := ')';
l_student_id VARCHAR2 (50);
l_student_num VARCHAR2 (50);
l_subject VARCHAR2 (50);
l_insert_stmnt VARCHAR2 (1000);
/* Check to see if the file exists using the UTL_FILE.fgetattr function.*/
dbms_output.put_line ('l_length is: '||l_length);
dbms_output.put_line ('l_blocksize is: '||l_blocksize);
/* Opening the File.
It is mandatory to open the file before starting any operations on the files.
The File is opened using the UTL_FILE.fopen function. It has three parameters.
Directory_name, file_name, read (r) or write (w) mode. */
l_file_handler := UTL_FILE.fopen (l_dir,'Test_UTL_Read_File.csv','r');
l_file_handler1 := UTL_FILE.fopen (l_dir,'Test_UTL_Write_File.csv','w');
l_file_handler2 := UTL_FILE.fopen (l_dir,'Test_UTL_Error_File.csv','w');
dbms_output.put_line ('File is successfully readable...');
--Below are the different UTL_FILE Exceptions
UTL_FILE.put_line (l_file_handler2, 'File location is invalid: '||SUBSTR (SQLERRM, 1, 200));
'The open_mode parameter in FOPEN is invalid. '||SUBSTR (SQLERRM, 1, 200));
'File handle is invalid: '||SUBSTR (SQLERRM, 1, 200));
'File could not be opened or operated on as requested: '
||SUBSTR (SQLERRM, 1,200));
'Destination buffer too small, or operating system error
occurred during the read operation: '||SUBSTR (SQLERRM, 1, 200));
'Operating system error occurred during the write operation: '
UTL_FILE.put_line (l_file_handler2, 'Other Error: '||SQLERRM);
/*Now once the file is opened - read the contents of the file
The UTL_FILE.GET_LINE procedure reads the text from the open files
identified by the file handle and places the text
in the output buffer paramter.*/
l_count := 0;
l_count := l_count+1;
UTL_FILE.GET_LINE (l_file_handler, l_new_line);
l_first_comma := INSTR (l_new_line, ',', 1, 1);
l_second_comma := INSTR (l_new_line, ',', 1, 2);
l_student_id := SUBSTR (l_new_line, 1, l_first_comma-1);
l_student_num := SUBSTR (l_new_line, l_first_comma+1, l_second_comma - l_first_comma - 1 );
l_subject := SUBSTR (l_new_line, l_second_comma + 1);
l_subject := REGEXP_REPLACE(l_subject,'(^[[:space:]]*|[[:space:]]*$)');
l_insert_stmnt := l_var1
exception when others
dbms_output.put_line ('Exception occurred in main block: '||SQLERRM);
After the UTL_File completes the Write process into a file Test_UTL_Write_File.csv, then the final output is as below: