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

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


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

Обратите внимание, как я позаботился о возвращении управления из данной функции только в одном месте. Если возврат управления происходит в нескольких местах, не забудьте в каждом из них вызывать функцию term(myCtx).

Теперь переходим к остальным функциям. Следующая функция обрабатывает даты, переданные как параметры в режиме IN и OUT. Мы будем:

принимать параметр типа DATE в режиме IN;

форматировать его как строку с помощью соответствующих функций библиотеки OCI для трассировки (для работы с данными типа DATE предлагается около 16 функций OCI);

добавлять один месяц к дате с помощью соответствующей функции OCI;

присваивать новую дату параметру, переданному в режиме OUT;

преобразовывать только что присвоенную дату в строку и выдавать ее;

наконец, вызывать функцию term и возвращать управление.

#ifdef WIN NT declspec (dllexport)

#endif

void pass date

(OCIExtProcContext * ctx /* CONTEXT */,

OCIDate * p idate /* OCIDATE */,

short p idate i /* INDICATOR short */,

OCIDate * p odate /* OCIDATE */,

short * p odate i /* INDICATOR short */

char buffer[255];

ub4 buff len;

char * fmt = dd-mon-yyyy hh24:mi:ss ;

myCtxStruct *myCtx;

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

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

if (p idate i = OCI IND NOTNULL)

buff len = sizeof(buffer);

if (OCIDateToText(myCtx->errhp, p idate, fmt, strlen(fmt),

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

raise application error(myCtx,ERROR OCI ERROR,

%s , lastOciError(myCtx));

else

debugf(myCtx, Входной параметр типа date ел значение %.*s ,

buff len, buffer) ; if (OCIDateAddMonths(myCtx->errhp, p idate, 1, p odate)

!= OCI SUCCESS)



1318 Глава 18

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

else

*p odate i = OCI IND NOTNULL;

buff len = sizeof(buffer);

if (OCIDateToText(myCtx->errhp, p odate, fmt, strlen(fmt), NULL, -1, &buff len,buffer) ! = OCI SUCCESS)

raise application error (myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

else {

debugf(myCtx,

В1ходной параметр типа date получил значение %.*s , buff len, buffer) ;

term(myCtx);}

Теперь разберемся, что необходимо для приема и передачи строк. Работать со строками несколько проще, чем с данными типа NUMBER и DATE, поскольку они передаются просто как строки ASCII, завершаемые нулем. Для всех строк, передаваемых в режиме OUT, будет использоваться параметр MAXLEN. Параметр MAXLEN задает для возвращаемой строки максимальный размер буфера, который может изменяться при каждом вызове. Дело в том, что буфер предоставляет вызывающая среда, и при каждом вызове может передаваться в режиме OUT другой параметр другого размера. В рез-тате внешняя процедура сможет учесть размер и предотвратить переполнение буфера. Она проинформирует вызывающую среду о том, что предоставлен слишком маленький буфер, и сообщит, какого размера он должен быть.

#ifdef WIN NT declspec (dllexport)

#endif

void pass str

(OCIExtProcContext * ctx /* CONTEXT */,

char * p istr /* STRING */,

short p istr i /* INDICATOR short */,

char * p ostr /* STRING */,

short * p ostr i /* INDICATOR short */,

int * p ostr ml /* MAXLEN int */

myCtxStruct *myCtx;

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



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

1319

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

(p istr i = OCI IND NOTNULL)

l istr l = (*p ostr ml

strlen(p istr);

> l istr l)

strcpy(p ostr, p istr) ; strupr(p ostr);

*p ostr i = OCI IND NOTNULL;

else {

raise application error(myCtx, ERROR STR TOO SMALL,

в1ходной буфер размером %d байт должен быть длиной не ->менее%d байт ,

*p ostr ml, l istr l+l);

term(myCtx);

На примере следующей функции я продемонстрирую использование типа binaryinteger. Тип binaryinteger в PL/SQL представляет 32-битовое целое число со знаком. Передать его проще всего. Значения этого типа передаются естественным для программиста на языке С образом. Эта функция просто проверит входное значение и присвоит его (умноженное на 10) выходному параметру:

#ifdef WIN NT

declspec (dllexport)

#endif

void pass int (OCIExtProcContext

int short

int *

short

p iINT p iINT i

P oINT

p oINT i

/* CONTEXT */,

/* int */,

/* INDICATOR short

/* int */,

/* INDICATOR short

myCtxStruct*myCtx;

if ((myCtx = init(ctx))

NULL ) return;

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

(p iINT i == OCI IND NOTNULL)

<

debugf(myCtx, Первый параметр типа INT еет значение %d , p iINT) ;

*p oINT = p iINT*10; *p oINT i = OCI IND NOTNULL;

debugf(myCtx, Устанавливаем выходному параметру типа INT ->значение%d , *p oINT) ;



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

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