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