|
Программирование >> Oracle
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. Таблицу соответствий типов данных см. далее.
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |