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

1 ... 292 293 294 [ 295 ] 296 297 298 ... 469


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

1299

Строка 14: p in INDICATOR short. Я сообщаю серверу Oracle, что следующий параметр в С-функции - индикаторная переменная типа short, которая позволит определить, имеет ли параметр p in значение NULL. Хотя это необязательно, я всегда передаю индикаторную переменную вместе с каждым параметром. Если этого не делать, нельзя будет определить во внешней процедуре, передано ли значение NULL, или вернуть из нее значение NULL.

Строка 15: p out OCINumber. Я сообщаю серверу Oracle, что следующий после индикаторной процедуры параметр функции тоже имеет тип OCINumber. В данном случае он будет передаваться как OCINumber *. Таблицу соответствий типов данных см. далее.

Строка 16: p out INDICATOR short. Я сообщаю серверу Oracle, что следующий

параметр - индикаторная переменная для параметра p out, и она должна быть типа short. Поскольку параметр p out передается в режиме OUT, эта индикаторная переменная позволит мне сообщить вызывающему, имеет ли параметр, переданный в режиме OUT, значение NULL. Поэтому этот параметр передается как данные типа short * (указатель), чтобы можно было не только читать значение, но и устанавливать его.

С учетом этого, давайте рассмотрим прототип С-функции, соответствующий только что созданной PL/SQL-процедуре. Этот прототип должен иметь следующий вид:

18 19

21 22 23 24

--void pass number (

OCIExtProcContext OCINumber short OCINumber *

short

/* 1

контекст

/* 2 : P IN */

/* 3 : P IN (индикатор)

/* 4 : P OUT */

/* 5 : P OUT (индикатор) */

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

27 28

29 30 31 3 2 33 34 35

37 38 39 40

procedure pass(p in in date, p out out date) as

language С name pass date library demoPass: with context parameters (CONTEXT,

p in OCIDate, pin INDICATOR short, p out OCIDate, p out INDICATOR short);

void pass date (

OCIExtProcContext *, /* 1 :

OCIDate *, /* 2 :

short , /* 3 :

OCIDate *, /* 4 :

контекст */ P IN * /

P IN (индикатор) P OUT */



1300

Глава 18

41 42

short

5 : P OUT (индикатор) */

Давайте рассмотрим, как передавать и принимать данные типа varchar2 - в этом случае сервер будет сопоставлять строки типу данных char * - указателю на строку символов.

45 46 47 48 49 50 51

in varchar2, p out out varchar2)

library demoPassing

procedure pass(p in as

language С name pass str with context parameters (CONTEXT,

p in STRING, p in INDICATOR short, pout STRING, p out INDICATOR short, p out MAXLEN int) ;

-- void pass str

-- (

-- OCIExtProcContext

/* 1

: контекст */

char

/* 2

: P IN */

short

/* 3

: P 1N (индикатор) */

char

/* 4

: P OUT */

short

/* 5

P OUT (индикатор) */

/* 6 :

P OUT (максимальная длина)

-- );

В этом коде мы впервые столкнулись с использованием параметра MAXLEN. Он требует от сервера Oracle передать внешней процедуре максимальный размер передаваемого в режиме OUT параметра p out. Поскольку мы возвращаем строку, важно знать ее максимально возможную длину, чтобы предотвратить перезапись буфера. Для всех строковых типов, передаваемых в режиме OUT, я настоятельно рекомендую использовать параметр MAXLEN.

Теперь давайте рассмотрим, как передавать тип PL/SQL BOOLEAN, которому будет сопоставляться тип int языка С:

64 65 66

68 69 70 71 72

73 74

76 78

procedure pass(p in in boolean, p out out boolean) as

language С name pass bool library demoPassing with context parameters (CONTEXT,

p in int, p in INDICATOR short, p out int, p out INDICATOR short);

void pass bool

OCIExtProcContext int short int short

/* 1 : контекст */

/* 2 : P IN */

/* 3 : P IN (индикатор)

/* 4 : P OUT */

/* 5 : P OUT (индикатор) */

Рассмотрим пример для типа данных CLOB. Мы передаем тип данных PL/SQL CLOB как тип данных OCILobLocator языка С. Обратите внимание, что в этом случае если



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

1301

параметр передается в режиме OUT, функция должна принимать указатель на указатель. Это позволяет в функции на языке С изменять не только содержимое, на которое указ1вает локатор большого объекта, но и сам этот локатор, т.е. при необходимости сослаться на другой большой объект:

p out in out clob)

83 84 85 86 87

89 90 91 92 93

94 95

96 97 98

procedure pass(p in in clob, as

language С name pass clob library demoPassing

with context parameters (CONTEXT,

p in OCILobLocator, p in INDICATOR short, p out OCILobLocator, p out INDICATOR short) ;

void pass clob

OCIExtProcContext

: контекст */

OCILobLocator

: P IN */

short

3 :

P IN (индикатор) */

OCILobLocator

: P OUT */

short

5

P OUT (индикатор) */

)

Затем следуют три процедуры, передающие и принимающие массивы, данные типа наборов в Oracle. Поскольку сопоставления типов во всех трех случаях очень похожи, рассмотрим все их одновременно. С-функции для этих трех процедур имеют абсолютно одинаковые прототипы - каждая получает данные типа OCIColl, независимо от передаваемого типа набора:

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123

procedure pass(p in in numArray, p out out numArray) as

language С name pass numArray library demoPassing with context parameters (CONTEXT,

p in OCIColl, p in INDICATOR short,

p out OCIColl, p out INDICATOR short);

void pass numArray

OCIExtProcContext *,

OCIColl *, /*

short , /*

OCIColl **, /*

short * /*

1 : контекст */

2 : P IN */ 3 : P IN (индикатор)

4 : P OUT */

5 : P OUT (индикатор) */

in dateArray, p out out dateArray)

procedure pass(p in as

language С name pass dateArray with context parameters (CONTEXT,

p in OCIColl, p in INDICATOR short, p out OCIColl, p out INDICATOR short);

library demoPassing



1 ... 292 293 294 [ 295 ] 296 297 298 ... 469

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