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

1 ... 301 302 303 [ 304 ] 305 306 307 ... 469


1326

Глава 18

debugf(myCtx, Элемент добавлен в конец другого массива );

*p out i

OCI IND NOTNULL;

term(myCtx);

#ifdef WIN NT declspec (dllexport) #endif

void pass dateArray (OCIExtProcContext *

/* CONTEXT */,

OCIColl

short

OCIColl short *

p in P in i

p out p out i

/* /*

OCICOL */, INDICATOR short */,

OCICOL */,

INDICATOR short

ub4 arraySize;

boolean exists;

OCIDate * ocidate; int i;

char * fmt = Day, Month YYYY hh24:mi:ss ;

ub4 buff len;

char buffer[255];

myCtxStruct*myCtx;

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

(p in i

OCI IND NULL)

raise application error(myCtx, ERROR ARRAY NULL,

Входной массив - NULL ) ;

else if (OCICollSize(myCtx->envhp, myCtx->errhp,

p in, &arraySize) != OCI SUCCESS)

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

else {

debugf(myCtx, Входной массив состоит из %d элементов , arraySize);

for(i =0; i < arraySize; i++) {

if (OCICollGetElem( myCtx->envhp, myCtx->errhp, p in, i,

&exists, (dvoid*)&ocidate, 0) != OCI SUCCESS)

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));



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

break;

buff len = sizeof(buffer);

if (OCIDateToText(myCtx->errhp, ocidate, fmt, strlen(fmt),

NULL, -1, &buff len, buffer) != OCI SUCCESS)

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

break;

debugf(myCtx, p in[%d] = %.*s , i, buff len, buffer);

if (OCICollAppend(myCtx->envhp,myCtx->errhp, ocidate, 0, *p out ) != OCI SUCCESS)

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

break;

debugf(myCtx, Элемент добавлен в конец другого массива ) ;

*p out i = OCI IND NOTNULL;

term(myCtx);

В завершение рассмотрим функции, непосредственно возвращающие значения. Они выглядят немного необычно, поскольку в PL/SQL используются функции без параметров, возвращающие значения, но соответствующие функции на языке С должны принимать ряд параметров. Другими словами, простейшей функции PL/SQL без параметров будет соответствовать С-функция с формальными параметрами. Эти формальные параметры будут использоваться внешней процедурой для передачи серверу Oracle следующих данных:

индикаторной переменной, показывающей, вернула ли функция значение NULL;

текущей длины данных строкового типа или типа RAW.

С этими параметрами мы уже встречались, просто странно, что они передаются функции.

#ifdef WIN NT declspec (dllexport)

#endif

OCINumber * return number (OCIExtProcContext * ctx, short * return i)

double ournumber = 123.456;

OCINumber * returnvalue; myCtxStruct*myCtx;

*return i = OCI IND NULL;



1328 Глава 18

if ((myCtx = init(ctx)) = NULL) return NULL; debugf(myCtx, Входим в функцию, возвращающую Number );

Здесь необходимо выделить память для возвращаемого числа. Нельзя использовать стековую переменную, поскольку при возврате значения она выходит из области действия. При выделении памяти с помощью функции malloc произойдет утечка пам Использовать статическую переменную тоже нельзя, поскольку из-за кэширования шних процедур другой сеанс может изменить значение, на которое мы сослались, по его возврата (но до того, как сервер Oracle его скопирует). Единственно корректн1й способ - выделить память следующим образом:

return value =

(OCINumber *)OCIExtProcAllocCallMemory(ctx, sizeof(OCINuntoer)) ; if(return value == NULL)

raise application error(myCtx, ERROR OCI ERROR, %s ,

не хватает памяти );

else 1

if (OCINumberFromReal(myCtx->errhp, &our number,

sizeof(our number), return value) != OCI SUCCESS)

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

*return i = OCI IND NOTNULL;

term(myCtx);

return return value;

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

#ifdef WIN NT declspec (dllexport) #endif

OCIDate * return date (OCIExtProcContext * ctx, short * return i)

OCIDate * return value; myCtxStruct*myCtx;

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

debugf(myCtx, Вход в функцию, возвращаюю данные типа Date >;

return value =

(OCIDate *)OCIExtProcAllocCallMemory(ctx, sizeof(OCIDate)); if (return value == NULL)



1 ... 301 302 303 [ 304 ] 305 306 307 ... 469

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