|
Программирование >> Oracle
Внешние процедуры на языке С
Итак, в таблице приводятся внешние типы данных, соответствующие типу данных SQL или PL/SQL. Я рекомендую использовать стандартные типы, поскольку с ними проще всего работать в функциях на языке С. Внешний тип данных очень похож на тип данных языка С, но надо пойти на шаг дальше. Поскольку любой тип данных SQL или PL/SQL может задаваться для параметра, передаваемого в режиме in, in out, out или определять тип возвращаемого значения функции, при определении фактического типа данных языка С необходимо дополнительное уточнение. В общем случае параметры, которые возвращаются или передаются в режиме in, передаются по значению, а параметры в режимах in out, out или передаваемые по ссылке явно, передаются через указатели, по ссылке. В следующей таблице показано, какой тип данных в С надо использовать для соответствующего внешнего типа данных и режима передачи параметра:
1306 Глава 18
Код на языке С Теперь можно переходить к реализации библиотеки на языке С. Начнем с общего шаблона, который я использую для внешних процедур. Этот шаблон включает стандартные заголовочные файлы, заголовочный файл Oracle OCI и три функции: debu oci error и raise application error. Эти функции обеспечивают поддержку механизма трассировки (debugf) и общей обработки ошибок (oci error и raise application error). Я просто копирую этот файл в каждый новый проект создания внешних процедур и начинаю разработку с него. #include<stdio.h> #include <stdlib.h> #include<time.h> #include <string.h> #include <errno.h> #include<ctype.h> #include<oci.h> #ifdef WIN NT #define INI FILE NAME c:\\WtempWextproc.ini #else #define INI FILE NAME /tmp/extproc.ini #endif #definestrupr(a) {char * cp; for(cp=a;*cp;*cp=toupper(*cp), cp++);} Выше представлено начало используемого мною шаблона на языке С. Я включаю заголовочные файлы, а также задаю местонахождение файла параметров. Есть много способов задать местонахождение этого файла на этапе выполнения. Например, если бы внешняя процедура создавалась для выполнения в среде Windows, можно было бы ис- Внешние процедуры на языке С 1307 пользовать функции Windows RegOpenKeyEx, RegQueryInfoKey и RegEnumValue для получения сведений о местонахождении файла параметров из системного реестра. В среде UNIX можно использовать переменную среды. В этом примере я просто явно указываю местонахождение в коде программы. Это вполне допустимо, поскольку можно потребовать, чтобы параметры инициализации помещались в известный стан-дартн1й файл (например, в файл /еtс/имя внешней процедуры.ога в ОС UNIX или с:\имя внешней процедуры\имя внешней процедуры.ога в Windows). Теперь переходим к самому коду. В следующей части определяется контекст. Он содержит то, что в обычной программе принято задавать в глобальных переменных. Мы не можем использовать глобальные переменные во внешней процедуре, поскольку это абсолютно ненадежно. Кроме того, поскольку статические данные будут инициализироваться при каждом вызове, использование глобальных переменных в любом случае будет некорректным. Для получения и установки контекста внешней процедуры мы будем использовать средства функционального интерфейса управления контекстом библиотеки OCI. В представленную ниже структуру можно добавлять любые переменные, содержащие информацию о состоянии, которую нужно сохранять между вызовами. Я определил следующие глобальные переменные. OCIExtProcContext * ctx. Контекст, который передается каждой внешней процедуре. Он потребуется во многих случаях, в частности при обработке ошибок. OCIEnv * envhp. Указатель на среду OCI. Он понадобится практически при каждом обращении к функции OCI. OCISvcCtx * svchp. Дескриптор службы OCI. Он понадобится во многих (но не во всех) вызовах функций OCI. OCIError * errhp. Дескриптор ошибки OCI. Он будет использоваться практически во всех вызовах функций OCI для обработки возможных ошибок. int curr lineno и char * curr filename. Эти переменные будут использоваться про- цедурой трассировки. Имя файла исходного кода и номер строки, из которой вызвана процедура трассировки, будут запоминаться, чтобы при выдаче сообщения было понятно, из какой строки и какого файла было выдано сообщение. Это пригодится при отладке с нуля . В главе 10 я писал о снабжении кода средствами трассировки и отладки - во внешних процедурах это особенно важно. ub1 debugf flag. Флаг, определяющий, выдаются ли трассировочные сообщения. Если этот флаг не установлен, мы проигнорируем обращения к debugf (функция debugf представлена ниже). Это позволит оставить вызовы функции трассировки в коде и при передаче его в производственную эксплуатацию, чтобы при необходимости трассировку легко можно было включить. char debugf path[255]. Эта переменная задает каталог, в который будут выдаваться отладочные сообщения. char debugf filename[50]. Эта переменная задает имя файла отладочн1х сообщений в указанном выше каталоге.
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |