UTL_FILE详解

包UTL_FILE 提供了在操作系统层面上对文件系统中文件的读写功能。非超级用户在使用包UTL_FILE中任何函数或存储过程前必须由超级用户授予在这个包上的EXECUTE权限。例如:我们使用下列命令对用户mary进行授权:

GRANT EXECUTE ON PACKAGE SYS.UTL_FILE TO mary;

如果使用包UTL_FILE中的函数和存储过程访问文件,那么操作系统中的用户enterprisedb必须在要访问的目录和文件上有相应的读写权限。如果没有相应权限的话,在执行包UTL_FILE中函数或存储过程的时候,就会产生异常。

在引用文件的时候,要使用到一个文件句柄,来表示对文件的读或写。文件句柄是通过包 UTL_FILE中名称为UTL_FILE.FILE_TYPE的公有变量来定义的。我们必须声明一个类型为FILE_TYPE的变量来接收通过函数 FOPEN返回的文件句柄。这个文件句柄将用于随后在文件上的所有操作。

对于文件系统上目录的引用是通过使用目录名称,或者由CREATE DIRECTORY命令为目录分配的化名来实现的。

下面的表中列出了包UTL_FILE中允许使用的存储过程和函数。

表 7-44 在包UTL_FILE中允许使用的函数/存储过程

 

函数/存储过程

返回类型

描述

FCLOSE(file IN OUT)

n/a

关闭由参数file所指定的文件。

FCLOSE_ALL

n/a

关闭所有打开的文件。

FCOPY(location, filename, dest_dir, dest_file [, start_line [, end_line ] ])

n/a

将指定目录location中文件filename代拷贝到目录dest_dir中的文件dest_file,要拷贝的文件内容范围是从参数start_line开始,到end_line结束。

FFLUSH(file)

n/a

强制将缓冲区中的数据写到由参数file标识的磁盘文件上。

FOPEN(location, filename, open_mode [, max_linesize ])

FILE_TYPE

打开目录location下,文件名为filename的文件。

FREMOVE(location, filename)

n/a

从文件系统中删除指定的文件。

FRENAME(location, filename, dest_dir, dest_file [, overwrite ])

n/a

更改指定文件的名称。

GET_LINE(file, buffer OUT)

n/a

从参数file指定的文件中把一行文本读到变量,缓冲区中。

IS_OPEN(file)

BOOLEAN

确定指定文件是否已经打开。

NEW_LINE(file [, lines ])

n/a

将行结束符写到文件中。

PUT(file, buffer)

n/a

将缓冲区buffer的内容写到指定文件中。存储过程PUT不写入行结束符。

PUT_LINE(file, buffer)

n/a

将缓冲区buffer的内容写到指定文件中,存储过程PUTL_LINE会在文件中写入行结束符。

PUTF(file, format [, arg1 ] [, ...])

n/a

将格式化的字符串写入指定文件中。我们可以最多可以指定5个可替代参数(从arg1到arg5)在参数format进行替换。

7.4.1 FCLOSE

存储过程FCLOSE关闭一个已打开的文件。

FCLOSE(file

 IN OUT FILE_TYPE)

参数

file

一个类型为FILE_TYPE的变量,包含一个要被关闭的文件的句柄。

7.4.2 FCLOSE_ALL

存储过程FCLOSE_ALL关闭所有已打开的文件。如果没有需要关闭的文件,存储过程也会执行成功。

FCLOSE_ALL

7.4.3 FCOPY

存储过程FCOPY把一个文件中文本拷贝到另外一个文件中。

FCOPY(location

 VARCHAR2, filename

 VARCHAR2,
dest_dir VARCHAR2, dest_file VARCHAR2
[, start_line PLS_INTEGER [, end_line PLS_INTEGER ] ])

参数

location

表示目录名称,存放在pg_catalog.edb_dir.dirname中,这个目录包含要拷贝的文件。

filename

要拷贝文件的名称。

dest_dir

表示目录名称,存放在pg_catalog.edb_dir.dirname中,是源文件要拷贝到目的目录。

dest_file

目标文件的名称。

start_line

源文件中文本行号,用于指定开始拷贝的位置。缺省值是1。

end_line

源文件中最后一行要拷贝文本的行号。如果省略这个参数或者这个参数为空,那么就一直拷贝到文件中最后一行。

示例

下面的示例中产生文件 c:/temp/empdir/empfile.csv的拷贝。这个文件中包含一个逗号分隔的列表,内容是表emp中的雇员信息。然后列出了empcopy.csv的内容。

CREATE DIRECTORY empdir AS 'C:/TEMP/EMPDIR';


DECLARE
v_empfile UTL_FILE.FILE_TYPE;
v_src_dir VARCHAR2(50) := 'empdir';
v_src_file VARCHAR2(20) := 'empfile.csv';
v_dest_dir VARCHAR2(50) := 'empdir';
v_dest_file VARCHAR2(20) := 'empcopy.csv';
v_emprec VARCHAR2(120);
v_count INTEGER := 0;
BEGIN
UTL_FILE.FCOPY(v_src_dir,v_src_file,v_dest_dir,v_dest_file);
v_empfile := UTL_FILE.FOPEN(v_dest_dir,v_dest_file,'r');
DBMS_OUTPUT.PUT_LINE('The following is the destination file, ''' ||
v_dest_file || '''');
LOOP
UTL_FILE.GET_LINE(v_empfile,v_emprec);
DBMS_OUTPUT.PUT_LINE(v_emprec);
v_count := v_count + 1;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE(v_empfile);
DBMS_OUTPUT.PUT_LINE(v_count || ' records retrieved');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);
END;

The following is the destination file, 'empcopy.csv'
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
14 records retrieved

7.4.4 FFLUSH

存储过程FFLUSH强制将缓冲区中未写入磁盘的内容写到磁盘文件中,并将缓冲区的内容清空。

FFLUSH(file

 FILE_TYPE)

参数

file

包含一个文件句柄的变量,类型为FILE_TYPE。

示例

调用存储过程NEW_LINE后,将缓冲区中的每一行记录强制写到磁盘中。

DECLARE

v_empfile UTL_FILE.FILE_TYPE;
v_directory VARCHAR2(50) := 'empdir';
v_filename VARCHAR2(20) := 'empfile.csv';
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
v_empfile := UTL_FILE.FOPEN(v_directory,v_filename,'w');
FOR i IN emp_cur LOOP
UTL_FILE.PUT(v_empfile,i.empno);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.ename);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.job);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.mgr);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.hiredate);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.sal);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.comm);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.deptno);
UTL_FILE.NEW_LINE(v_empfile);
UTL_FILE.FFLUSH(v_empfile);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Created file: ' || v_filename);
UTL_FILE.FCLOSE(v_empfile);
END;

7.4.5 FOPEN

函数FOPEN为I/O操作打开一个文件。

filetype

 FILE_TYPE FOPEN(location

 VARCHAR2, filename

 VARCHAR2,
open_mode VARCHAR2 [, max_linesize BINARY_INTEGER ])

参数

location

目录名称,存在pg_catalog.edb_dir.dirname中。这个目录包含着要打开的文件。

filename

被打开文件的名称。

open_mode

打开文件需要的模式。可允许的模式包括: a-向文件添加内容;r-从文件读取内容;w - 向文件写内容。

max_linesize

一行文本的最大长度,以字符为单位。在读模式中,如果试图读取一行长度超过max_linesize的值,那么会产生异常。在写模式和附加模式中, 如果尝试写一行长度超过max_linesize的文本,那么也会产生异常。当计算文本行是否超出最大行长度时,不包含行结束符。这种系统行为与 Oracle不兼容。-Oracle在做相同操作时是计算行结束符的。

filetype

类型为FILE_TYPE的变量,包含被打开文件句柄。

7.4.6 FREMOVE

存储过程FREMOVE用于从系统中删除一个文件。

FREMOVE(location

 VARCHAR2, filename

 VARCHAR2)

如果要删除的文件不存在,那么会产生一个异常。

参数

location

目录名称,存放在pg_catalog.edb_dir.dirname中,这个目录包含要删除的文件。

filename

要删除文件的名称。

示例

下面的示例删除了文件 empfile.csv

DECLARE

v_directory VARCHAR2(50) := 'empdir';
v_filename VARCHAR2(20) := 'empfile.csv';
BEGIN
UTL_FILE.FREMOVE(v_directory,v_filename);
DBMS_OUTPUT.PUT_LINE('Removed file: ' || v_filename);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);
END;

Removed file: empfile.csv

7.4.7 FRENAME

存储过程FRENAME修改一个文件的名称,这样我们可以把一个文件从一个位置移动到另外一个位置。

FRENAME(location

 VARCHAR2, filename

 VARCHAR2,
dest_dir VARCHAR2, dest_file VARCHAR2, [ overwrite BOOLEAN ])

参数

location

目录名称,存放在pg_catalog.edb_dir.dirname中,这个目录包含要改名的文件。

filename

要改名的源文件名称。

dest_dir

目录名称,存放在pg_catalog.edb_dir.dirname中,这个目录是被改名文件所在的目录。

dest_file

原始文件的新名称。

overwrite

如果设置为”true”,在dest_dir 目录中覆盖任何名为dest_file 的文件。若设置为”false”,就会产生异常。这是缺省情况。

示例

下面我们将文件C:/TEMP/EMPDIR/empfile.csv重新命名,这个文件包含一个逗号分隔的列表,内容是表emp中雇员的信息。然后列出重新命名后的文件 C:/TEMP/NEWDIR/newemp.csv的内容。

CREATE DIRECTORY "newdir" AS 'C:/TEMP/NEWDIR';


DECLARE
v_empfile UTL_FILE.FILE_TYPE;
v_src_dir VARCHAR2(50) := 'empdir';
v_src_file VARCHAR2(20) := 'empfile.csv';
v_dest_dir VARCHAR2(50) := 'newdir';
v_dest_file VARCHAR2(50) := 'newemp.csv';
v_replace BOOLEAN := FALSE;
v_emprec VARCHAR2(120);
v_count INTEGER := 0;
BEGIN
UTL_FILE.FRENAME(v_src_dir,v_src_file,v_dest_dir,
v_dest_file,v_replace);
v_empfile := UTL_FILE.FOPEN(v_dest_dir,v_dest_file,'r');
DBMS_OUTPUT.PUT_LINE('The following is the renamed file, ''' ||
v_dest_file || '''');
LOOP
UTL_FILE.GET_LINE(v_empfile,v_emprec);
DBMS_OUTPUT.PUT_LINE(v_emprec);
v_count := v_count + 1;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE(v_empfile);
DBMS_OUTPUT.PUT_LINE(v_count || ' records retrieved');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);
END;

The following is the renamed file, 'newemp.csv'
7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20
7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30
7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30
7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20
7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30
7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10
7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20
7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10
7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30
7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20
7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30
7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20
7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10
14 records retrieved

7.4.8 GET_LINE

存储过程GET_LINE从一个指定文件中读取一行不包含行结束符的文本。如果在文件中已经没有文本行可供读取的话,那么会产生名为NO_DATA_FOUND的异常。

GET_LINE(file

 FILE_TYPE, buffer

 OUT VARCHAR2)

参数

file

类型为FILE_TYPE的变量,包含已打开文件句柄的变量。

buffer

用于接收文件中文本行的变量。

示例

下面这个匿名代码块,读取并显示了文件empfile.csv中记录。

DECLARE

v_empfile UTL_FILE.FILE_TYPE;
v_directory VARCHAR2(50) := 'empdir';
v_filename VARCHAR2(20) := 'empfile.csv';
v_emprec VARCHAR2(120);
v_count INTEGER := 0;
BEGIN
v_empfile := UTL_FILE.FOPEN(v_directory,v_filename,'r');
LOOP
UTL_FILE.GET_LINE(v_empfile,v_emprec);
DBMS_OUTPUT.PUT_LINE(v_emprec);
v_count := v_count + 1;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE(v_empfile);
DBMS_OUTPUT.PUT_LINE('End of file ' || v_filename || ' - ' ||
v_count || ' records retrieved');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);
END;

7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20
7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30
7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30
7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20
7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30
7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10
7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20
7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10
7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30
7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20
7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30
7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20
7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10
End of file empfile.csv - 14 records retrieved

7.4.9 IS_OPEN

函数IS_OPEN用来确认指定文件是否已打开。

status

 BOOLEAN IS_OPEN(file

 FILE_TYPE)

参数

file

类型为FILE_TYPE的变量,包含被测试文件的句柄。

status

如果指定文件已打开,那么返回”true”,否则返回”false”。

7.4.10 NEW_LINE

向一个包含双倍行距的雇员记录列表写入行结束符。

NEW_LINE(file

 FILE_TYPE [, lines

 INTEGER ])

参数

file

类型为FILE_TYPE的变量,包含要写入行结束符的文件句柄。

lines

要写入的行结束符的数量。缺省是1。

示例

向一个包含双倍行距的雇员记录列表写入行结束符。

DECLARE

v_empfile UTL_FILE.FILE_TYPE;
v_directory VARCHAR2(50) := 'empdir';
v_filename VARCHAR2(20) := 'empfile.csv';
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
v_empfile := UTL_FILE.FOPEN(v_directory,v_filename,'w');
FOR i IN emp_cur LOOP
UTL_FILE.PUT(v_empfile,i.empno);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.ename);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.job);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.mgr);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.hiredate);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.sal);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.comm);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.deptno);
UTL_FILE.NEW_LINE(v_empfile,2);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Created file: ' || v_filename);
UTL_FILE.FCLOSE(v_empfile);
END;

Created file: empfile.csv

然后显示这个文件的内容:

C:/TEMP/EMPDIR>TYPE empfile.csv


7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20

7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30

7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30

7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20

7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30

7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30

7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10

7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20

7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10

7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30

7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20

7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30

7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20

7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10

7.4.11 PUT

存储过程PUT将一行字符串写入一个文件中。在字符串结尾的行结束符不会写入到文件中。我们可以使用存储过程NEW_LINE在文件中增加行结束符。

PUT(file

 FILE_TYPE, buffer

 { DATE | NUMBER | TIMESTAMP |
VARCHAR2 })

参数

file

类型为FILE_TYPE的变量,包含一个文件句柄,字符串将写到这个文件中。

buffer

要写入指定文件中的文本。

示例

下面的示例使用存储过程PUT创建了一个逗号分隔的列表,列表的内容是表emp中的雇员信息。

DECLARE

v_empfile UTL_FILE.FILE_TYPE;
v_directory VARCHAR2(50) := 'empdir';
v_filename VARCHAR2(20) := 'empfile.csv';
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
v_empfile := UTL_FILE.FOPEN(v_directory,v_filename,'w');
FOR i IN emp_cur LOOP
UTL_FILE.PUT(v_empfile,i.empno);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.ename);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.job);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.mgr);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.hiredate);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.sal);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.comm);
UTL_FILE.PUT(v_empfile,',');
UTL_FILE.PUT(v_empfile,i.deptno);
UTL_FILE.NEW_LINE(v_empfile);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Created file: ' || v_filename);
UTL_FILE.FCLOSE(v_empfile);
END;

Created file: empfile.csv

下面是上面创建文件empfile.csv的内容:

C:/TEMP/EMPDIR>TYPE empfile.csv


7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20
7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30
7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30
7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20
7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30
7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10
7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20
7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10
7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30
7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20
7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30
7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20
7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10

7.4.12 PUT_LINE

存储过程PUT_LINE 向指定文件写入一行包含行结束符的文本。

PUT_LINE(file

 FILE_TYPE, buffer

 { DATE | NUMBER | TIMESTAMP |
VARCHAR2 })

参数

file

类型为FILE_TYPE的变量,包含一个文件的句柄。文本记录将写到这个文件中。

buffer

要写入指定文件中的文本。

示例

在下面的示例中,使用存储过程PUT_LINE创建了一个包含以逗号分隔列表的文件,内容是表emp中的雇员信息。

DECLARE

v_empfile UTL_FILE.FILE_TYPE;
v_directory VARCHAR2(50) := 'empdir';
v_filename VARCHAR2(20) := 'empfile.csv';
v_emprec VARCHAR2(120);
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
v_empfile := UTL_FILE.FOPEN(v_directory,v_filename,'w');
FOR i IN emp_cur LOOP
v_emprec := i.empno || ',' || i.ename || ',' || i.job || ',' ||
NVL(LTRIM(TO_CHAR(i.mgr,'9999')),'') || ',' || i.hiredate ||
',' || i.sal || ',' ||
NVL(LTRIM(TO_CHAR(i.comm,'9990.99')),'') || ',' || i.deptno;
UTL_FILE.PUT_LINE(v_empfile,v_emprec);
END LOOP;
DBMS_OUTPUT.PUT_LINE('Created file: ' || v_filename);
UTL_FILE.FCLOSE(v_empfile);
END;

下面就是上面创建的empfile.csv中内容:

C:/TEMP/EMPDIR>TYPE empfile.csv


7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20
7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30
7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30
7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20
7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30
7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10
7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20
7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10
7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30
7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20
7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30
7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20
7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10

7.4.13 PUTF

存储过程PUTF向文件写入一个格式化的字符串。

PUTF(file

 FILE_TYPE, format

 VARCHAR2 [, arg1

 VARCHAR2]
[, ...])

参数

file

类型为FILE_TYPE的变量,包含文件句柄。我们将把格式化的文本记录写到这个参数指向的文件。

format

用于写入文件的文本字符串格式。可以使用参数arg替代指定的字符串序列%s。指定的字符串序列/n表示新的一行。然而,要注意的是在 Postgres Plus Advanced Server中,必须以2个连续的反斜线而不是一个-//n来指定换行符。这个特性与Oracle不兼容。

arg1

最多可以有5个参数arg1...arg5 来替代格式字符串中出现的每个%s.按照第一个arg用于替代第一个出现的%s,第二个arg用于替代第二个%s。。这样的顺序进行替代。

示例

在下面的匿名代码块中产生了包含表emp中数据的格式化输出。需要注意的是E文本语法和格式字符串中出现的双反斜线不属于Oracle兼容特性。

DECLARE

v_empfile UTL_FILE.FILE_TYPE;
v_directory VARCHAR2(50) := 'empdir';
v_filename VARCHAR2(20) := 'empfile.csv';
v_format VARCHAR2(200);
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
v_format := E'%s %s, %s//nSalary: $%s Commission: $%s//n//n';
v_empfile := UTL_FILE.FOPEN(v_directory,v_filename,'w');
FOR i IN emp_cur LOOP
UTL_FILE.PUTF(v_empfile,v_format,i.empno,i.ename,i.job,i.sal,
NVL(i.comm,0));
END LOOP;
DBMS_OUTPUT.PUT_LINE('Created file: ' || v_filename);
UTL_FILE.FCLOSE(v_empfile);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);
END;

Created file: empfile.csv

下面就是上面所创建的文件empfile.csv的内容:

C:/TEMP/EMPDIR>TYPE empfile.csv


7369 SMITH, CLERK
Salary: $800.00 Commission: $0

7499 ALLEN, SALESMAN
Salary: $1600.00 Commission: $300.00

7521 WARD, SALESMAN
Salary: $1250.00 Commission: $500.00

7566 JONES, MANAGER
Salary: $2975.00 Commission: $0

7654 MARTIN, SALESMAN
Salary: $1250.00 Commission: $1400.00

7698 BLAKE, MANAGER
Salary: $2850.00 Commission: $0

7782 CLARK, MANAGER
Salary: $2450.00 Commission: $0

7788 SCOTT, ANALYST
Salary: $3000.00 Commission: $0

7839 KING, PRESIDENT
Salary: $5000.00 Commission: $0

7844 TURNER, SALESMAN
Salary: $1500.00 Commission: $0.00

7876 ADAMS, CLERK
Salary: $1100.00 Commission: $0

7900 JAMES, CLERK
Salary: $950.00 Commission: $0

7902 FORD, ANALYST
Salary: $3000.00 Commission: $0

7934 MILLER, CLERK
Salary: $1300.00 Commission: $0

你可能感兴趣的:(exception,manager,File,Integer,存储,buffer)