Выполнение хранимой процедуры

Назначение

Выполнение предварительно оттранслированной и сохраненной в БД пользовательской процедуры.

Параметры вызова

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 в двоичном представлении в виде специальной структуры, которая содержит последовательно:

  1. описатель возвращаемого значение (Result);

  2. количество выходных параметров (2 байта);

  3. описатели выходных параметров (если процедура создана с отладочной информацией, возвращаются также имена параметров);

  4. буфер возвращаемого значения и значений выходных параметров.

Описатель возвращаемого значения и описатель выходного параметра имеют следующую структуру:

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

Битовая маска атрибутов параметра:

  • PARM_FLAG_ISNULL – признак NULL-значения;

  • PARM_FLAG_ISCURSOR – признак курсора;

  • PARM_FLAG_NAMESENT – признак наличия имени параметра в буфере выборки данных RowBuf.

Expr

Зарезервировано для будущего использования.

Value

Позиция (смещение) данного возвращаемого значения в двоичном буфере выборки данных относительно его начала. Представление самого значения имеет следующий формат:

  • если для значения установлен признак наличия имени параметра, то по указанному смещению сначала находится имя: два байта длины и соответствующее количество символов. Далее следует само значение. Если признак наличия имени параметра не установлен, значение находится сразу по указанному смещению;

  • для типов данных CHAR и BYTE хранится соответствующее количество символов согласно описанию типа;

  • для целочисленных типов данных SMALLINT и INT хранятся два или четыре байта значения соответственно;

  • для вещественных чисел REAL и DOUBLE – 4 и 8 байт соответственно;

  • значения типов данных NUMERIC и DATE представляются в формате DECIMAL СУБД ЛИНТЕР – по 16 байт;

  • значение типа CURSOR содержит всю необходимую информацию для заполнения контрольного блока CBL, используемого для навигации по выборке с помощью соответствующих команд интерфейса нижнего уровня. Информация выдается в следующем виде:

    struct CR_INFO
     {
     L_WORD NumChan;  /* Номер канала */
     L_WORD LnBufRow; /* Размер одной записи в байтах */
     L_LONG RowId;    /* Текущий ROWID в выборке */
     L_LONG RowCount; /* Количество записей в выборке */
     L_LONG CodErr;   /* Текущий код завершения */
     };

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.