Выполнение хранимой процедуры
Назначение
Выполнение предварительно оттранслированной и сохраненной в БД пользовательской процедуры.
Параметры вызова
inter(CBL, NULL, OpBuf, [CondBuf], RowBuf);
Входные данные
Входными данными являются:
-
контрольный блок
CBL
; -
буфер оператора OpBuf.
В контрольном блоке должны быть заполнены поля:
Имя поля | Значение | |
---|---|---|
NumChan
| Номер канала | |
Command
|
4 пробела
| |
LnBufRow
| Длина буфера выборки данных | |
Node
| Имя ЛИНТЕР-сервера |
Буфер оператора
OpBuf
должен содержать SQL-выражение исполнения процедуры:
EXECUTE < имя процедуры >(< значения параметров >);
< значения параметров > представляют собой совокупность допустимых в SQL выражений, разделенных запятой. Некоторые из этих выражений могут отсутствовать (помечаются запятой). В случае пропуска фактических параметров и/или непривязке значений к параметрам формальные параметры получают значения по умолчанию (если для них заданы значения по умолчанию), либо NULL-значения в противном случае по умолчанию так же, как при вызове хранимой процедуры изнутри другой хранимой процедуры.
Для передачи логических значений используются целые числа (0
интерпретируется как
FALSE
, 1 – как
TRUE
) или символьные константы
'true'
и
'false'
(в любом регистре).
Выходные данные
Выходными данными являются:
-
контрольный блок
CBL
; -
буфер выборки данных
RowBuf
.
В контрольном блоке будут возвращены:
Имя поля | Значение | |
---|---|---|
CodErr
| Код завершения запроса к СУБД ЛИНТЕР | |
SysErr
| Код состояния ОС |
Результат выполнения процедуры возвращается в буфере
RowBuf
в двоичном представлении в виде специальной структуры,
которая содержит последовательно:
-
описатель возвращаемого значение (Result);
-
количество выходных параметров (2 байта);
-
описатели выходных параметров (если процедура создана с отладочной информацией, возвращаются также имена параметров);
-
буфер возвращаемого значения и значений выходных параметров.
Описатель возвращаемого значения и описатель выходного параметра имеют следующую структуру:
struct ARGPROC_OUT { L_BYTE Flags; /* Флаги значения */ L_BYTE Reserv; /* Зарезервировано */ #if _VER_MAX >= 550 L_WORD Expr; /* Идентификатор выражения */ #endif L_WORD Value; /* Смещение значения в буфере */ P_TYPE Type; /* Тип значения */ #if _VER_MAX >= 550 L_WORD Reserv2; /* Зарезервировано */ #endif };
Описатель возвращаемого значения (выходного параметра) содержит следующие поля:
Имя поля | Значение | |
---|---|---|
Flags |
Битовая маска атрибутов параметра:
| |
Expr | Зарезервировано для будущего использования. | |
Value |
Позиция (смещение) данного возвращаемого значения в двоичном буфере выборки данных относительно его начала. Представление самого значения имеет следующий формат:
| |
Type |
Описатель типа данных параметра, который имеет следующую структуру: struct P_TYPE { L_WORD length; /* Длина типа данных */ L_BYTE ntyp; /* Код типа данных */ L_BYTE prcs; /* Точность */ L_BYTE scale; /* Масштаб */ L_BYTE reserv; /* Резерв */ #if _VER_MAX >= 600 L_WORD charset; /* Идентификатор кодовой стр-цы */ #endif }; |
Описание
Выполнение хранимых процедур осуществляется последовательно в режиме квантования времени.
Допускается рекурсивный вызов процедуры. Глубина рекурсии ограничивается предоставленными ядру СУБД ЛИНТЕР ресурсами (размерами дисковой и оперативной памяти).
В рамках одной транзакции первая запущенная на выполнение хранимая процедура открывает для своей работы дочерний канал. Все последующие процедуры, вызываемые в рамках той же транзакции, переиспользуют этот канал, не открывая новых. Поэтому команды COMMIT/ROLLBACK в процедуре влияют не только на изменения, сделанные данной процедурой, но и на все изменения, осуществленные всеми вызванными ранее процедурами. Чтобы избежать этого, процедура должна использовать контрольные точки SAVEPOINT: установить точку сохранения в начале транзакции и подавать COMMIT/ROLLBACK до нее.
Примечание
Поскольку триггеры выполняются точно так же, как процедуры, все сказанное верно и для них. Кроме того, в контексте триггеров это дает еще один полезный эффект, поскольку все изменения совершаются триггерами по одному общему каналу, в случае нарушения логики работы, обнаруженного триггером, он может подать ROLLBACK, откатывающий изменения всех вызванных ранее триггеров и обеспечивающий целостность в рамках запроса.
Поскольку триггерные транзакции выполняются точно так же, как и процедурные, то все сказанное о процедурной транзакции верно и для триггерных. Кроме того, в контексте триггеров такой механизм обработки транзакций дает полезный эффект: поскольку все изменения совершаются триггерами по одному общему каналу, то в случае нарушения логики работы, обнаруженной триггером, он может подать команду ROLLBACK, откатывающую изменения всех вызванных ранее триггеров и обеспечивающую целостность БД в рамках текущего запроса обработки данных.
Коды завершения
Код | Описание | |
---|---|---|
NORMAL | Нормальное завершение | |
SMALLBUFKOR | Недостаточный размер буфера выборки данных | |
Proc_Raised_Exception |
Процедура завершилась с исключением. В этом случае поле
SysErr
контрольного блока будет содержать код исключения
(возможно положительное или отрицательное значение). Положительное
значение формируется ядром СУБД ЛИНТЕР при обработке
SQL-запросов,
входящих в тело процедуры. Отрицательное значение формируется системой
исполнения хранимых процедур (приложение
13)
| |
Proc_Not_Translated | Процедура не была оттранслирована (оттранслирована с ошибкой) | |
Proc_No_Memory | Недостаточно памяти для исполнения процедуры | |
Proc_Bad_Code | Ошибка в оттранслированном коде процедуры | |
Proc_Inv_Version | Неправильная версия оттранслированного кода процедуры (необходимо выполнить SQL-оператор ALTER PROCEDURE) | |
ERRPASSWORD | Нарушение привилегий |
Пример формирования команды
#include < string.h > #include < stdlib.h > #include "inter.h" L_LONG LinterExec(TCBL *pCBL, L_CHAR *ExecStat, void *Buf, L_WORD LenBuf) { memcpy(pCBL- >Command, " ", 4); pCBL- >LnBufRow=LenBuf; pCBL- >PrzExe &= ~Q_ASYNC; inter(pCBL, NULL, ExecStat, NULL, Buf); return pCBL- >CodErr; }
Пример использования команды
См. приложение 14.