Пакет UTL_FILE, который мы уже несколько раз использовали по ходу изложения, хорошо справляется с чтением и записью текстовых файлов. Очень часто, однако, необходимо обработать все файлы в указанном каталоге. Этого пакет не позволяет сделать. Для получения списков файлов каталога нет встроенных методов ни в SQL, ни в PL/SQL. На Java его очень легко получить. Вот как это делается:
tkyte@TKYTE816> create global temporary table DIR_LIST 2 (filename varchar2(255)) 3 on commit delete rows 4 / Table created.
В этой реализации я решил использовать для возвращения результатов из хранимой процедуры на Java временную таблицу. Я считаю этот метод наиболее удобным, потому что он позволяет в дальнейшем легко сортировать список и выбирать файлы с нужными именами.
Необходим следующий фрагмент Java-кода:
tkyte@TKYTE816> create or replace 2 and compile java source named "DirList" 3 as 4 import java.io.*; 5 import java.sql.*; 6 7 public class DirList 8 { 9 public static void getList(String directory) 10 throws SQLException 11 { 12 File path = new File(directory); 13 String[] list = path.list(); 14 String element; 15 16 for(int i = 0; i < list.length; i++) 17 { 18 element = list[i]; 19 #sql { INSERT INTO DIR_LIST (FILENAME) 20 VALUES (:element) }; 21 } 22 } 23 24 } 25 /
Java created.
Я решил использовать SQLJ, чтобы сократить программу. Подключение к базе данных уже выполнено, поэтому реализация с помощью интерфейса JDBC потребовала лишь нескольких дополнительных строк кода. Но с помощью препроцессора SQLJ выполнять SQL-операторы в Java так же просто, как и в PL/SQL. Теперь, конечно же, необходимо создать спецификацию вызова:
tkyte@TKYTE816> create or replace 2 procedure get_dir_list(p_directory in varchar2) 3 as language java 4 name 'DirList.getList(java.lang.String)'; 5 /
Procedure created.
Прежде чем запускать эту процедуру, следует учесть еще один нюанс. Необходимо предоставить процедуре право делать то, что она должна — читать список файлов каталога. В данном случае я обладаю правами администратора базы данных, поэтому могу предоставить соответствующие привилегии сам себе, но обычно приходится обращаться с соответствующим запросом к администратору. Если помните, во введении к этой главе я писал:
"... Java-код всегда работает с правами владельца ПО Oracle, поэтому хранимая процедура на Java при предоставлении соответствующих привилегий может переписать файл параметров инициализации сервера, INIT.ORA (или другие, еще более важные файлы, например файлы данных)."