接着上次,我们针对文件读进行详细解释。

假如,我们用上次的文件test.txt(DATA_PUMP_DIR目录),把里边的内容读入并在显示到画面上,这里我们还要用到使用UTL_FILE包。

代码如下:

SQL>SET SERVEROUT ON --SQL*Plus的画面输出有效
 SQL> DECLARE
 2 /文件句柄的声明/
 3 FH UTL_FILE.FILE_TYPE;
 4 /声明变量,以存储已读取行的内容/
 5 V_LINE VARCHAR2(32767);
 6 –
 7 BEGIN
 8 /以读取模式(R)打开文件⇒获取文件句柄/
 9 FH := UTL_FILE.FOPEN(‘DATA_PUMP_DIR’,‘test.txt’,‘R’);
 10 –
 11 LOOP
 12 /从文件句柄的文件里读取一行/
 13 UTL_FILE.GET_LINE(FH,V_LINE);
 14 /将该行显示在画面上/
 15 DBMS_OUTPUT.PUT_LINE(V_LINE);
 16 END LOOP;–重复上述处理
 17 –
 18 EXCEPTION
 19 WHEN NO_DATA_FOUND THEN
 20 /最后关闭文件/
 21 UTL_FILE.FCLOSE(FH);
 22 END;
 23 /

你好。←※这是文件里的内容。
您好吗?

PL/SQL过程成功完成。

我们重点说明一下上次写入的最大的不同的地方。

●(1)变量的声明:用于保存读取数据的(第5行)
因为要从文件中读取数据,所以需要保存读取数据的变量。
上述例子中第5行是变量的定义。V_LINE变量,定义是VACHAR2(32767)。
长度32767是PL/SQL程序中VARCHAR2的最大长度。
但并不是说必须是32767,可以根据自己的需求修改。

●(2)以读取模式打开文件(第9行)
与上次不同,这次以读取模式“R”。
这样就可以读取那个文件了。(写入模式是‘W’)

●(3)读取1行(第13行)
UTL_FILE.GET_LINE中,可以将一行数据加载到变量中。

语法结构如下。
UTL_FILE.GET_LINE(文件句柄,变量);
(在写入模式中,写一行用的是UTLFILE.PUT_LINE吧)

●(4)读取结束的判定处理(第19行)
UTL_FILE.GET_LINE读取结束的判定处理流程有点特殊:
首先,循环逐行读文件内容:第11~16行。
循环处理中重复从文件句柄中读取一行并显示该行。
在这个循环本上中没有结束判定处理哦?

通常,在基本循环结构(LOOP~END LOOP;)中,如果没有记述结束判定条件并退出循环(EXIT)处理,则会变成无限循环。

但是上述处理不会成为无限循环。

因为,使用UTLFILE.GET_LINE读取数据时,如果超过文件的末端读取数据时,则会出错。如果PL/SQL发生错误,则跳至例外处理部(EXCEPTION)。

因此,即使没有记述EXIT循环的处理,也不会变成无限循环。

这种情况下的错误是“NO_DATA_FOUND例外”。

因此关闭文件就可以在例外处理部的NO_DATA_FOUND例外处理程序(第19行)里边进行。

说到“NO_DATA_FOUND例外”,代表性的例子是SELECT~INTO语句结果为0行时的错误,UTLFILE.GET_LINE超过文件结尾读取时也会发生同样的错误。

通过这个异常判断,就可以是循环结束。

那么这次就到此为止。请期待下次。