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

1 ... 318 319 320 [ 321 ] 322 323 324 ... 469


Хранимые процедуры на языке Java 1379

но бьло сложно. Теперь же это почти тривиально. Есть, вероятно, сотни способов сделать это, но следующий фрагмент кода работает вполне удовлетворительно:

tkyte@TKYTE816> create or replace and compile

2 java source named Util

3 as

4 import java.io.*;

5 import java.lang.*;

7 public class Util extends Object

8 { 9

10 public static int RunThis(String[] args)

11 {

12 Runtime rt = Runtime.getRuntime();

13 int rc = -1;

15 try

16 {

17 Process p = rt.exec(args[0]);

19 int bufSize = 4096;

20 BufferedInputStream bis =

21 new BufferedInputStream(p.getInputStream(), bufSize);

22 int len;

23 byte buffer[] = new byte[bufSize]; 24

25 Выдаем то, что получено программой

26 while ((len = bis.read(buffer, 0, bufSize)) != -1)

27 System.out.write(buffer, 0, len);

29 rc = p.waitForO ;

30 }

31 catch (Exception e)

33 e.printStackTraceO;

34 rc = -1;

35 }

36 finally

37 {

38 return rc;

39 }

40 }

41 }

42 /

Java created.

Он позволяет выполнить любую программу и получить ее результаты либо в файле трассировки на сервере, либо, при использовании средств пакета DBMSJAVA, в буфере пакета DBMS OUTPUT. Это, однако, весьма мощное средство - при наличии соответствующих привилегий с его помощью можно выполнять любую команду от име-



1380

Глава 19

ни пользователя - владельца ПО Oracle. В данном случае я хочу иметь возможность получить список процессов с помощью утилиты /usr/bin/ps в ОС UNIX и \bin\tlist.exe в Windows. Для этого мне необходимы две привилегии:

tkyte@TKYTE816> BEGIN

2 dbms java.grant permission

3 (USER,

4 java.io.FilePermission,

5 - /usr/bin/ps, -- для UNIX

6 c:\bin\tlist.exe, -- для WINDOWS

7 execute);

9 dbmsiava.grant permission

10 (USER;

11 java.lang.RuntimePermission,

13 writeFileDescriptor);

14 end;

15 /

PL/SQL procedure successfully completed.

Ввашей системеможет отсутствоватьутилита tlist.exe. Она входит в состав набора инструментальных средств Windows Resource Toolkit и доступна не во всех Windom-системах. Этот пример просто показывает, что можно сделать, - отсутствие доступа к tlist.exe не помешает демонстрации. Этотметодможно использовать дм выполнения любой программы. Учтите, однако, что нужно быть внимательным, предоставляя права на выполнение программ с помощью пакета DBMS JAVA. Например, предоставление права на выполнение программы c:\winnt\system32\cmd.exe фактическиозначаетразрешениевыполнятьВСЕпрограммы, что очень опасно.

Первый вызов dbms java.grant permission позволяет запускать одну конкретную программу. При желании можно рискнуть и указать вместо имени программы символ *. позволит выполнять любые программы. Я не думаю, однако, что это разумно; явно ре-числяйте полные имена программ, в надежности которых вы уверены. Вторая привилегия позволяет генерировать результаты во время выполнения. Здесь придется использовать метасимвол *, поскольку я не знаю точно, куда именно будут выдаваться резтат: (в стандартный выходной поток, stdout, например, или куда-нибудь еще).

Теперь необходимо создать уровень связывания:

tkyte@TKYTE816> create or replace

2 function RUN CMD(p cmd in varchar2) return number

3 as

4 language java

5 name Util.RunThis(java.lang.String[]) return integer;

Function created.

tkyte@TKYTE816> create or replace procedure rc(

2 as



Хранимые процедуры на языке Java

1381

3 x number;

4 begin

5 x := run cmd(p cmd);

6 if (x о 0)

7 then

8 raise program error;

9 end if;

10 end;

11 /

Procedure created.

Здесь я создал еще один уровень абстракции выше функции связывания, чтобы можно выполнять программу как процедуру. Давайте посмотрим, как это работает:

tkyte@TKYTE816> set serveroutput on size 1000000 tkyte@TKYTE816> exec dbms java.set output(1000000)

PL/SQL procedure successfully completed.

tkyte@TKYTE816> exec rc(C:\WINNT\system32\cmd.exe Volume in drive С has no label. Volume Serial Number is F455-B3C3

Directory of C:\oracle\DATABASE 05/07/2001 05/07/2001 11/04/2000

11/04/2000

11/04/2000

05/07/2001

05/10/2001 05/06/2001

01/26/2001 04/19/2001 05/07/2001 01/30/2001 9 File(s) 3 Dir(s)

/c dir)

10:13a

<DIR>

10:13a

<DIR>

06:28p

<DIR>

ARCHIVE

06:37p

inittkyte816.ora

06:28p

31,744

ORADBA.EXE

09:07p

1,581

oradim.log

07:47p

2,560

pwdtkyte816.ora

08:43p

3,584

pwdtkyte816.ora.hold

11:31a

3,584

pwdtkyte816.xxx

09:34a

21,309

sqlnet.log

10:13a

2,424

test.sql

02:10p

348,444

l.tar

415,277 bytes 13,600,501,760 bytes free

PL/SQL procedure successfully completed. Мы получили список файлов каталога ОС.

Получение времени с точностью до миллисекунд

Примеры становятся все меньше, короче и выполняются быстрее. Это я и хочу подчеркнуть. С помощью небольших фрагментов Java-кода, примененных в соответствующих местах, можно существенно расширить функциональные возможности.

В Oracle 9i эта функция станет избыточной, поскольку эта версия поддерживает вре-менн1е отметки с точностью менее секунды. Но при необходимости такая точность измерения времени достижима и в предыдущих версиях:

tkyte@TT<YTE;816> create or replace java source

2 named MyTimestamp

3 as



1 ... 318 319 320 [ 321 ] 322 323 324 ... 469

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