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

1 ... 299 300 301 [ 302 ] 303 304 305 ... 469


1320

Глава 18

term(myCtx);

Теперь рассмотрим передачу параметров PL/SQL типа BOOLEAN. Тип BOOLEAN

языка PL/SQL в данном случае сопоставляется типу int языка С. Значение 1 представляет истину, а значение 0 - ложь, как и следовало ожидать. Эта функция просто проверяет входной параметр (не пуст ли он) и устанавливает выходной параметр равным отрицанию входного. И в этом случае, поскольку обеспечивается простое сопоставление со встроенным типом языка С, реализовать эту функцию очень легко. Для обмена данными не надо использовать дескрипторы среды или вызовы функций. Функция просто устанавливает выходной параметр равным отрицанию входного:

#ifdef WIN NT

declspec (dllexport)

#endif

void pass bool

(OCIExtProcContext * ctx /* CONTEXT */,

int p ibool /* int */,

short p ibool i /* INDICATOR short */,

int * p obool /* int */,

short * p obool i /* INDICATOR short */)

myCtxStruct*myCtx;

if ((myCtx = init(ctx)) = NULL) return; debugf(myCtx, Вход в функцию Pass Boolean ) ;

if (p ibool i = OCI IND NOTNULL)

*p obool = !p ibool;

*p obool i = OCI IND NOTNULL;

term(myCtx) ;

Теперь займемся передачей параметров типа RAW. Поскольку переменные типа VARCHAR2 в PL/SQL могут иметь длину не более 32 Кбайт, мы всегда будем использовать более простой для взаимодействия внешний тип данных RAW. Он соответствуете языке С типу данных unsigned char *, который представляет собой указатель на байт: данных. Работая с данными типа RAW, мы всегда будем получать атрибут LENGTH. обязательно, поскольку нет другого способа определить, какое количество данных надо обрабатывать. Мы также всегда будем получать атрибут MAXLEN для всех параметров, переданных в режиме OLT и имеющих переменную длину, чтобы избежать потенциальной перезаписи буфера. Этот атрибут, хотя технически и не обязателен, слишком важен, чтобы его не использовать. Данная функция просто копирует входной буфере выходной:

#ifdef WIN NT declspec (dllexport)

#endif



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

1321

void pass raw (OCIExtProcContext

unsigned char short int

unsigned char short * int * int *

p iraw p iraw i p iraw l

p oraw p oraw i p oraw ml p oraw l

/* CONTEXT */, /* RAW */,

/* INDICATOR short

/* LEN INT */,

/* RAW */,

/* INDICATOR short */, /* MAXLEN int */,

/* LENGTH int */

myCtxStruct*myCtx;

if ((myCtx - init(ctx)) debugf(myCtx, if (p iraw i

if (p iraw l <= *p oraw ml)

memcpy(p oraw, p iraw, p iraw l);

NULL ) return;

Вход в функцию Pass long raw ) ;

OCI IND NOTNULL)

*p oraw l *p oraw i

p iraw l;

OCI IND NOTNULL;

else {

raise application error(myCtx, ERROR RAW TOO SMALL, Буфер размером %d байт должен быть размером не менее %d байт , *p oraw ml, p iraw l);

else

*p oraw i *p oraw l

term(myCtx);

OCI IND NULL;

Последняя функция, обрабатывающая скалярные данные, работает с большими объектами. Работать с большими объектами ничуть не сложнее, чем с данными типа DATE или NUMBER. Имеется несколько функций библиотеки OCI, позволяющих читать и записывать большие объекты, копировать и сравнивать их, и т.д. В этом примере используются функции для определения длины и последующего копирования большого входного объекта в выходной. Эта функция требует, чтобы в вызывающей среде б1л проинициализирован большой объект, передаваемый в режиме OUT (либо путем выбора локатора LOB из существующей строки таблицы, либо с помощью подпрограммы dbms lob.createtemporary). Хотя я демонстрирую работу только с большим объектом типа CLOB, реализации для объектов типа BLOB и BFILE будут очень похожи: для всех трех



1322

Глава 18

типов используется тип данных OCILobLocator. Подробнее о функциях, работающих с данными типа OCILobLocator, можно прочитать в руководстве Oracle Call Interface Programmers Guide. Приведенная функция просто копирует входной объект типа CLOB в выходной.

#ifdef WIN NT

declspec (dllexport)

#endif

void pass clob

(OCIExtProcContext * ctx

OCILobLocator short

OCILobLocator short *

/* CONTEXT */,

p iCLOB /* OCILOBLOCATOR */, p iCLOB i /* INDICATOR short */, p oCLOB /* OCILOBLOCATOR */,

p oCLOB i /* INDICATOR short */

ub4 lob length;

myCtxStruct* myCtx;

if ((myCtx = init(ctx)) = NULL ) return;

debugf(myCtx, Вход в функцию Pass Clob );

(p iCLOB i = OCI IND NOTNULL && *p oCLOB i

OCI IND NOTNULL)

debugf(myCtx, оба больших объекта - NOT NULL ) ;

if (OCILobGetLength(myCtx->svchp, myCtx->errhp,

p iCLOB, Slob length) != OCI SUCCESS)

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

else

debugf(myCtx, Длина входного большого объекта была %d ,

lob length);

if (OCILobCopy(myCtx->svchp, myCtx->errhp, *p oCLOB, p iCLOB, lob length, 1, 1) != OCI SUCCESS)

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

else

debugf(myCtx, Mi скопировали большой объект! ) ;

else

raise application error(myCtx, ERROR CLOB NULL,

%s %s объект типа clob был ст (NU) , (p iCLOB i - OCI IND NULL)? входной : ,

-к *



1 ... 299 300 301 [ 302 ] 303 304 305 ... 469

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