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

1 ... 291 292 293 [ 294 ] 295 296 297 ... 469


1296

Глава 18

данные булева типа (BOOLEAN);

данные типа RAW (размером до 32 Кбайт);

большие объекты (для всех данных размером >32 Кбайт);

массивы строк;

массивы чисел;

массивы дат.

Для этого необходимо сначала создать несколько типов наборов. Они будут представлять массивы строк, чисел и дат:

tkyte@TKYTE816> create or replace type numArray as table of number

2 / Type created.

tkyte@TKYTE816> create or replace type dateArray as table of date

2 / Type created.

tkyte@TKYTE816> create or replace type strArray as table of varchar2(255)

2 / Type created.

Теперь можно создавать спецификацию пакета. Она представляет собой набор перегруженных процедур для тестирования передачи параметров. Каждая процедура имеет параметры, передаваемые в режиме IN и OUT, за исключением версии для данных типа CLOB, в которой параметр передается в режиме IN/OUT. Клиент должен инициализировать параметр LOB IN OUT, а внешняя процедура заполнит этот объект:

tkyte@TKYTE816> create or replace package demo passing pkg

2 as

3 procedure pass(p in in number, p out out number);

5 procedure pass(p in in date, p out out date); 6

7 procedure pass(p in in varchar2, p out out varchar2) ; 8

9 procedure pass(p in in boolean, p out out boolean);

11 procedure pass(p in in CLOB, p out in out CLOB); 12

13 procedure pass(p in in numArray, p out out numArray) ; 14

15 procedure pass(p in in dateArray, p out out dateArray) ; 16

17 procedure pass(p in in strArray, p out out strArray);

Нельзя использовать перегрузку для процедур, использующих параметры типа RAW и INT, поскольку вызов PASS(RAW, RA будет совпадать по сигнатуре с PASS(VARCHAR2,VARCHAR2), a PASS(INT,INT) - с PASS(NUMBER,NUMBER).

Поэтому для этих двух типов данных я в виде исключения создам процедуры со специальными именами:



Внешние процедуры на языке С 1297

19 procedure pass raw(p in in RAW, p out out RAW) ;

21 procedure pass int(p in in binary integer,

22 p out out binary integer);

Наконец, реализую несколько функций, возвращающих значения, чтобы продемонстрировать, как они реализуются. Создадим по функции для каждого из основных скалярных типов данных:

25 function return number return number; 26

27 function return date return date; 28

29 function return string return varchar2;

31 end demo passing pkg;

32 /

Package created.

Операторы CREATE TYPE позволяют создать необходимые типы массивов. С их помощью мы определили новые SQL-типы; numArray - вложенная таблица чисел, dateArray - вложенная таблица дат и strArray - вложенная таблица строк типа VARCHAR2(255). Мы создали также спецификацию пакета, который собираемся реализовать, так что можно приступать к реализации. Я представлю ее шаг за шагом. Начнем с создания библиотеки:

tkyte@TKYTTE816> create or replace library demoPassing

2 as

3 С:\demo passing\extproc.dll

Library created.

Этот оператор, как и в рассмотренном ранее примере, где проверялась настройка учетной записи SCOTT/TIGER, просто определяет для сервера Oracle место хранения библиотеки demoPassing; в данном случае она находится в файле C:\demo passing\ extproc.dll. Тот факт, что эта DLL-библиотека еще не создана, не имеет значения. Объект-библиотека необходим для компиляции тела PL/SQL-пакета, который мы собираемся создавать. Библиотеку extproc.dll мы создадим чуть позже. Оператор создания библиотеки можно успешно выполнить даже при ее отсутствии.

Теперь переходим к телу пакета:

tkyte@TKYTE816> create or replace package body demo passing pkg 2 as

4 procedure pass(p in in number,

5 p out out number)

6 as

7 language С

8 name pass number

9 library demoPassing

10 with context

11 parameters (



1298

Глава 18

12 CONTEXT,

13 p in OCINumber,

14 p in INDICATOR short,

15 p out OCINumber,

16 p out INDICATOR Short);

Итак, на первый взгляд, все начинается как обычно: оператор CREATE OR REPLACE PACKAGE и тело процедуры PROCEDURE Pass( ... ) as ... , но затем появляется отличие от обычной хранимой процедуры. Мы создаем спецификацию вызова, а не PL/SQL-код. Спецификация вызова - это метод сопоставления PL/SQL-типов встроенным типам данных языка, на котором создается внешняя процедура. Например, выше выполнено сопоставление параметра p in number типу данных OCINumber языка С. Ниже представлено построчное описание того, что делается в данном случае.

Строка 7: language С. Задаем язык. Создаются внешние процедуры на яз1ке С, хотя можно их создавать и на языке Java (но этому посвящена следующая глава).

Строка 8: name pass number . Задаем имя функции на языке С, которую

вызывать из библиотеки demoPassing. Для сохранения регистра символов необходимо использовать идентификатор в кавычках (поскольку для языка С регистр символов имеет значение). Обычно все идентификаторы в Oracle переводятся в верхний регистр, но если взять их в двойные кавычки, регистр символов при записи в базу данных будет сохранен. Это имя должно точно совпадать с именем С-функции, вплоть до регистра символов.

Строка 9: library demoPassing. Указываем имя библиотеки, которая будет содержать соответствующий код. Это имя совпадает с именем, заданным в представленном ранее операторе CREATE LIBRARY.

Строка 10: with context. Хотя это и не обязательно, я всегда передаю контекст.

Этот контекст необходим для выдачи осмысленных сообщений об ошибках и использования функций OCI или Pro*С.

Строка 11: parameters. Начало списка параметров. Мы явно задаем последовательность и типы передаваемых параметров. Это, как и передавать контекст, делать не обязательно, но я всегда стараюсь описывать параметры явно. Вместо использования стандартн1х соглашений и периодического их угадывания я явно сообщаю серверу Oracle, какие значения и в каком порядке ожидаю получить.

Строка 12: CONTEXT. Это ключевое слово, стоящее в списке параметров пер-

вым, требует от сервера Oracle передать в качестве первого параметр типа OCIExtProcContext *. Это ключевое слово можно задавать в любом месте списка параметров, но обычно его указывают первым. OCIExtProcContext - тип данных, определяемый функциональным интерфейсом OCI и представляющий информацию о сеансе на сервере.

Строка 13: p in OCINumber. Я сообщаю серверу Oracle, что следующий параметр

в моей С-функции должен быть типа OCINumber. В данном случае он будет передаваться как OCINumber *, указатель на данные типа OCINumber. Таблицу соответствий типов данных см. далее.



1 ... 291 292 293 [ 294 ] 295 296 297 ... 469

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