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

1 ... 294 295 296 [ 297 ] 298 299 300 ... 469


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

Тип данных SQL или PL/SQL

Внешний тин данных

Стандартный тип

CHAR, CHARACTER, LONG, NCHAR, NVARCHAR2, ROWID, VARCHAR2, VARCHAR

string, ocistring

string

LONG RAW, RAW

raw, ociraw

BFILE, BLOB, CLOB, NCLOB

ociloblocator

ociloblocator

NUMBER, DEC, DECIMAL, INT, INTEGER, NUMERIC,

SMALLINT

[unsigned]char, [unsigned]short, [unsigned]int, [unsigned]long, sb1. sb2, sb4, ub1, ub2, ub4. size t, ocinumber

ocinumber

DATE

Ocidate

ocidate

Абстрактные типы данных (АТД)

Dvoid

dvoid

Наборы (вложенные таблицы, массивы VARRAY)

Ocicoll

ocicoll

Итак, в таблице приводятся внешние типы данных, соответствующие типу данных SQL или PL/SQL. Я рекомендую использовать стандартные типы, поскольку с ними проще всего работать в функциях на языке С. Внешний тип данных очень похож на тип данных языка С, но надо пойти на шаг дальше. Поскольку любой тип данных SQL или PL/SQL может задаваться для параметра, передаваемого в режиме in, in out, out или определять тип возвращаемого значения функции, при определении фактического типа данных языка С необходимо дополнительное уточнение. В общем случае параметры, которые возвращаются или передаются в режиме in, передаются по значению, а параметры в режимах in out, out или передаваемые по ссылке явно, передаются через указатели, по ссылке. В следующей таблице показано, какой тип данных в С надо использовать для соответствующего внешнего типа данных и режима передачи параметра:

Внешний тип данных

Тип в языке С для параметров IN и возвращаемых значений

Тип в языке С для параметров IN OUT, OUT и при передаче по ссылке

[unsigned] char

[unsigned] char

[unsigned] char *

[unsigned] short

[unsigned] short

[unsigned] short *

[unsigned] int

[unsigned] int

[unsigned] int

[unsigned] long

[unsigned] long

[unsigned] long *

size t

size t

size t *

sb1 *

sb2 *

sb4 *

ub1 *

ub2 *

ub4 *



1306

Глава 18

Внешний тип данных

Тип в языке С для параметров IN и возвращаемых значений

Тип в языке С для параметров IN OUT, OUTи при передаче по ссылке

float

float

float *

double

double

double *

string

char *

char *

unsigned char *

unsigned char *

Ociloblocator

OCILobLocator *

OCILobLocator **

Ocinumber

OCINumber *

OCINumber *

Ocistring

OCIString *

OCIString *

Ociraw

OCIRaw

OCIRaw *

Ocidate

OCIDate

OCIDate *

Ocicoll

OCIColl *

OCIColl **

dvoid *

dvoid

Код на языке С

Теперь можно переходить к реализации библиотеки на языке С. Начнем с общего шаблона, который я использую для внешних процедур. Этот шаблон включает стандартные заголовочные файлы, заголовочный файл 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х сообщений в указанном выше каталоге.



1 ... 294 295 296 [ 297 ] 298 299 300 ... 469

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