Перейти к основному содержимому
Версия: 7.0

Предыдущее значение (PREV)

Оператор предыдущего значения создает свойство, которое возвращает значение заданного свойства на начало сессии изменений (то есть текущее значение в базе данных без учета изменений, сделанных в сессии). Результирующее свойство имеет тот же класс значения, что и исходное свойство. Вместе с производными от него операторами изменений этот оператор обеспечивает отслеживание изменений в сессии: он дает доступ к состоянию "до", с которым сравнивается текущая сессия.

к сведению

Этот оператор всегда использует область видимости начала сессии. О том, как это взаимодействует с обработкой событий, см. канонический раздел про событийный режим.

Если класс параметра не определяется ни условием, ни значением свойства, перед использованием предыдущего значения этого свойства в ограничении ограничьте его область определения условием принадлежности классу. Это может понадобиться, например, для оператора выбора с ветвью, возвращающей постоянное значение для любого объекта. Без такого ограничения в текущей реализации возможна ошибка запуска сервера при построении сообщения о нарушении ограничения (см. пример ниже).

Язык​

Для объявления свойства, возвращающего предыдущее значение, используется оператор PREV.

Примеры​

CLASS Order;
sum = DATA NUMERIC[10,2] (Order);

// Самый частый случай — чтение значения "до" внутри обработчика события, реагирующего
// на изменение. PREV(sum(o)) возвращает значение на начало сессии — значение из базы,
// игнорирующее изменения в текущей сессии. Предикаты изменения (CHANGED, SET, DROPPED,
// ...) являются производными от PREV — это булевы сравнения с текущим значением, а сам
// PREV даёт доступ к фактическому предыдущему значению.
WHEN CHANGED(sum(Order o)) DO
MESSAGE 'Сумма изменена: ' + PREV(sum(o)) + ' → ' + sum(o);
CLASS Item;
noLimit = DATA BOOLEAN ();
maxQuantity = DATA NUMERIC[10,2] (Item);
quantity = DATA NUMERIC[10,2] (Item);

// без условия IS класс параметра i не определяется самим свойством: когда noLimit[] истинно, значение 1000000
// верно для любого объекта, а предыдущее значение такого свойства в ограничении приводит к ошибке при старте сервера
limit (Item i) = (IF noLimit() THEN 1000000 ELSE maxQuantity(i)) IF i IS Item;
// измененное в сессии количество не может превысить предел, действовавший на начало сессии
// оператор изменений обязателен: условие quantity(i) > PREV(limit(i)) без него не проверялось бы никогда
CONSTRAINT CHANGED(quantity(Item i)) AND quantity(i) > PREV(limit(i)) MESSAGE 'Количество превышает предел';