Триггер
Модераторы: m0p3e, edward_K, Модераторы
Триггер
Я решила поработать с триггерами взяла стандартный пример из хэлпа. Заменила только имя таблицы. Причем триггер должен обращаться к Vip интерфейсу. Все компилится без ошибок, но когда запускаю, галактика вылетает, и причем вставляет в указанную таблицу кучу записей, только с одним заполненным полем waywps.num_work, если же я не ставлю функцию ClearBuffer(#waywps), то запись вставляет, но поле waywps.num_work остается нулевым, хотя сообщения выдаются. Помогите, пожалуйста, с этим разобраться.
//объявление объектного интерфейса
objInterface objTrig;
function DoInsert(cRec : comp) : word;
end;
//объявление Vip-интерфейса
#include ObjTrig.vih
vipInterface vipTrig implements objTrig;
//===================
//реализация Vip-интерфейса
interface vipTrig;
//логическая таблица для связанной таблицы
create view as select * from waywps;
function DoInsert(cRec : comp) : word;
{
ClearBuffer(#waywps);
waywps.num_work := 9999;
message('вошла');
result := insert current waywps;
}
//------------------------------------------------------
HandleEvent
cmOnVipUnload: message('dddd');
end;
end.
//===========================================
var GlobVipTrig : vipTrig new;
handler with replace Trig_After on trigger waywps after insert
action
{
var buf : record as table waywps;
GetTableBuffer(buf); // считываем старый буфер
GlobVipTrig.doInsert(buf.NRec);
result := true;
}
Версия Atlantis 5.4.14, галактика 8.01.
//объявление объектного интерфейса
objInterface objTrig;
function DoInsert(cRec : comp) : word;
end;
//объявление Vip-интерфейса
#include ObjTrig.vih
vipInterface vipTrig implements objTrig;
//===================
//реализация Vip-интерфейса
interface vipTrig;
//логическая таблица для связанной таблицы
create view as select * from waywps;
function DoInsert(cRec : comp) : word;
{
ClearBuffer(#waywps);
waywps.num_work := 9999;
message('вошла');
result := insert current waywps;
}
//------------------------------------------------------
HandleEvent
cmOnVipUnload: message('dddd');
end;
end.
//===========================================
var GlobVipTrig : vipTrig new;
handler with replace Trig_After on trigger waywps after insert
action
{
var buf : record as table waywps;
GetTableBuffer(buf); // считываем старый буфер
GlobVipTrig.doInsert(buf.NRec);
result := true;
}
Версия Atlantis 5.4.14, галактика 8.01.
вот пример:
Пример 2.
Данный триггер вызывается при добавлении записи в таблицу HozOper. В триггере производится изменение текущей записи таблицы HozOper и добавление новой записи в таблицу HozForm.
//======================================================
//объявление объектного интерфейса
objInterface objTrig;
function DoInsert(cRec : comp) : word;
end;
//объявление Vip-интерфейса
vipInterface vipTrig implements objTrig;
//======================================================
//реализация Vip-интерфейса
interface vipTrig;
//------------------------------------------------------
//логическая таблица для связанной таблицы
create view as select * from HozForm;
//------------------------------------------------------
//функция добавления записи в связанную таблицу
function DoInsert(cRec : comp) : word;
{
ClearBuffer(#HozForm);
HozForm.cNRec := cRec; // связка с родительской таблицей (HozOper)
HozForm.Formula := 'Новая формула';
result := insert current HozForm;
}
//------------------------------------------------------
handleEvent
cmOnVipUnload: message('dddd');
end;
end.
//======================================================
// Для модификации текущей записи лучше сделать trigger before insert.
// Он выполняется перед добавлением записи в таблицу HozOper.
// Установка значений выполняется с использованием GetTableBufferP и SetTableBuffer.
handler with replace Trig_Before on trigger HozOper before insert
action
{
//переменная буфера с позицией
var buf : record as table HozOper with x$position;
GetTableBufferP(buf); // Считываем буфер
buf.Name2 := 'Новое значение'; // Изменяем значение поля
SetTableBuffer(buf); // Сохраняем буфер
result := true;
}
//======================================================
// Для вставки новых записей лучше сделать trigger after insert.
// Триггер выполняется после добавления записи в родительскую таблицу(HozOper).
// К моменту вызова триггера HozOper.NRec уже определен.
// Переменную объекта лучше сделать на уровне приложения, чтобы
// при каждом срабатывании триггера объект каждый раз не создавался.
// При первом обращении к VIP-объекту произойдет автоматическая
// инициализация. Освобождение произойдет при выходе из приложения
var GlobVipTrig : vipTrig new;
handler with replace Trig_After on trigger HozOper after insert
action
{
var buf : record as table HozOper;
GetTableBuffer(buf); // считываем старый буфер
GlobVipTrig.doInsert(buf.NRec); // добавляем запись в таблицу НozForm
result := true;
}
а к SetTableBuffer- написано что, если меняю ключевое, а поле которое я хочу изменить не являеться ключевым!
Пример 2.
Данный триггер вызывается при добавлении записи в таблицу HozOper. В триггере производится изменение текущей записи таблицы HozOper и добавление новой записи в таблицу HozForm.
//======================================================
//объявление объектного интерфейса
objInterface objTrig;
function DoInsert(cRec : comp) : word;
end;
//объявление Vip-интерфейса
vipInterface vipTrig implements objTrig;
//======================================================
//реализация Vip-интерфейса
interface vipTrig;
//------------------------------------------------------
//логическая таблица для связанной таблицы
create view as select * from HozForm;
//------------------------------------------------------
//функция добавления записи в связанную таблицу
function DoInsert(cRec : comp) : word;
{
ClearBuffer(#HozForm);
HozForm.cNRec := cRec; // связка с родительской таблицей (HozOper)
HozForm.Formula := 'Новая формула';
result := insert current HozForm;
}
//------------------------------------------------------
handleEvent
cmOnVipUnload: message('dddd');
end;
end.
//======================================================
// Для модификации текущей записи лучше сделать trigger before insert.
// Он выполняется перед добавлением записи в таблицу HozOper.
// Установка значений выполняется с использованием GetTableBufferP и SetTableBuffer.
handler with replace Trig_Before on trigger HozOper before insert
action
{
//переменная буфера с позицией
var buf : record as table HozOper with x$position;
GetTableBufferP(buf); // Считываем буфер
buf.Name2 := 'Новое значение'; // Изменяем значение поля
SetTableBuffer(buf); // Сохраняем буфер
result := true;
}
//======================================================
// Для вставки новых записей лучше сделать trigger after insert.
// Триггер выполняется после добавления записи в родительскую таблицу(HozOper).
// К моменту вызова триггера HozOper.NRec уже определен.
// Переменную объекта лучше сделать на уровне приложения, чтобы
// при каждом срабатывании триггера объект каждый раз не создавался.
// При первом обращении к VIP-объекту произойдет автоматическая
// инициализация. Освобождение произойдет при выходе из приложения
var GlobVipTrig : vipTrig new;
handler with replace Trig_After on trigger HozOper after insert
action
{
var buf : record as table HozOper;
GetTableBuffer(buf); // считываем старый буфер
GlobVipTrig.doInsert(buf.NRec); // добавляем запись в таблицу НozForm
result := true;
}
а к SetTableBuffer- написано что, если меняю ключевое, а поле которое я хочу изменить не являеться ключевым!
Радует фраза конечноЯ же в первый раз

На счет рекурсии - есть функ. RecursionLevel , с помощью которой можно отследить вложенность. Например в случае необходимости создания подчиненных записей в таблице при создании родительской записи. В принципе на что вы и напоролись.