Программирование >>  Oracle 

1 ... 328 329 330 [ 331 ] 332 333 334 ... 469


Использование объено-реляционн1х средств 1411

167 /

Type body created.

В представленном коде перехватываются все исключительные ситуации пакета UTL FILE и возбуждаются другие исключительные ситуации с помошью процедуры RAISE APPLICATION ERROR. Это основная причина инкапсуляции средств пакета UTL FILE в объектный тип. Пакет UTL FILE возбуждает исключительные ситуации с описанием USER-DEFINED EXCEPTION. Эти исключительные ситуации определены разработчиками пакета UTL FILE, и при их возбуждении сервер Oracle выдает сообщение: USER-DEFINED EXCEPTION . Оно не слишком информативно и не помогает разобраться в причинах ошибки. Я предпочитаю использовать процедуру RAISE APPLICATION ERROR, которая позволяет задать значения встроенных функций SQLCODE и SQLERRM, возвращаемые клиенту. Чтобы увидеть, как это может повлиять на отладку, достаточно рассмотреть следующий небольшой пример, демонстрирующий, какого рода сообщения об ошибках можно получить от пакета UTL FILE и объектного типа FILETYPE:

tkyte@TK:E816> declare

2 futl file.file type :=utl file.fopen(c:\temp\bogus,

3 foo.txt, w) ;

4 begin

5 utl file.fclose(f);

6 end;

declare

ERROR at line 1:

ORA-06510: PL/SQL: unhandleduser-defined exception ORA-06512: at SYS.UTL FILE , line 98 ORA-06512: at SYS.UTL FILE , line 157 ORA-06512: at line 2

tkyte@TKYTE816> declare

2 f fileType := fileType.open(c:\temp\bogus,

3 foo.txt, w) ;

4 begin

5 f.close;

6 end;

7 / declare

ERROR at line 1:

ORA-20001: The path c:\temp\bogus is not in the utl file dir path c:\temp, c:\oracle

ORA-06512: at TKYTE.FILETYPE , line 54

ORA-06512: at line 2

Нетрудно понять, с помощью какого сообщения проще определить причину ошибки. Второе сообщение об ошибке (при наличии у владельца типа доступа к представлению V$PARAMETER) очень точно объясняет причину ошибки: использован недопус-



1412

Глава 20

тимый каталог, не указанный в параметре инициализации UTL FILE DIR. Даже при отсутствии доступа к представлению V$PARAMETER будет выдано следующее сообще-

ние:

ERROR at line 1:

ORA-20001: INVALID PATH: File location or filename was invalid. ORA-06512: at TKYTE.FILETYPE , line 59

ORA-06512: at line 2

которое все равно лучше, чем краткое user-defined exception.

В этом типе также следует обратить внимание на возможность установки предпочтительных стандартных значений параметров подпрограмм. Например, до версии Oracle 8.0.5 пакет UTL FILE имел ограничение на максимальную длину строки - 1023 байт. Если попытаться выдать более длинную строку, пакет UTL FILE возбуждает исключительную ситуацию. По умолчанию точно так же происходит и в Oracle 8i. Если явно не указать максимальный размер строки при вызове UTL FILE.FOPEN, ограничение 1023 байт остается. Я лично предпочитаю по умолчанию устанавливать максимальную длину строки равной 32 Кбайт. В начале кода я также задал стандартный режим открытия файла - на чтение (R). Поскольку в 90 процентах случаев я использую пакет UTL FILE для чтения файла, такое стандартное значение для меня имеет смысл.

Теперь давайте проверим работу объектного типа и рассмотрим использование всех функций и процедур. Сначала создадим файл (предполагается, что мы работаем в Windows NT, существует каталог c:\temp и параметр инициализации UTL FILE DIR содержит c:\temp) и запишем в него определенные данные. Затем мы закроем этот файл, сохранив данные. Это продемонстрирует возможности записи типа FILETYPE:

tkyte@TKYTE816> declare

2 3 4

6 7 8

9 10

16 17

18 19

fileType := fileType.open(c:\terrp\ foo.txt, w);

begin

if (f.isOpen)

then

dbms output.put line(Файл end if;

открыт);

for i in 1

f.put(i end loop; f.put line(ll);

10 loop

f.newline(5); for i in 1 .. 5 loop

f.putline(cтpoкa

end loop;

ll i);

f.putf(%s %s, Hello, World); f.flush;



Использование объектно-реляционн1х средств 1413

24 f.close;

25 end;

26 /

Файл открыт

PL/SQL procedure successfully completed.

Далее продемонстрировано чтение файла с помощью объекта типа FILETYPE. Откроем только что записанный файл и убедимся, что прочитаны именно те данные, которые в нем содержатся:

tkyte@TKYTE816> declare

2 ffileType :=fileType.open(c:\temp, foo.txt);

3 begin

4 if (f.isOpen)

5 then

6 dbms output.put line(Файл открыт);

7 end if;

9 dbms output.put line

10 (строка 1: (должна быть l,2,...,11) f.get line);

12 for i in 2 .. 6

13 loop

14 dbms output.put line

15 (строка i : (должна быть пустой) f.get line);

16 end loop;

18 for i in 7 .. 11

19 loop

20 dbms output.put line

21 (строка to char(i+l)

22 : (должна быть строка N) f.get line) ;

23 end loop; 24

25 dbms output.put line

26 (строка 12: (должна быть Hello World) f.get line);

28 begin

2 9 dbms output.put line(f.get line);

30 dbms output.put line(B предыдущей операторе должна -> произойти ошибка ) ;

31 exception

32 when NO DATA FOUND then

33 dbms output.put line(получили no data found, как и -> ожидалось) ;

3 4 end;

35 f.close;

36 end;

37 /

Файл открыт

строка 1: (должна быть l,2,...,ll)l,2,3,4,5,6,7,8,9,10,ll



1 ... 328 329 330 [ 331 ] 332 333 334 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика