powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / after and before UPDATE триггера
3 сообщений из 3, страница 1 из 1
after and before UPDATE триггера
    #37457680
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день! Собственно вопрос не новый, но решения не нашел.

Задача следующая:
Клиент(таблица customer с полями customer_id,customer_name,balance) платит(таблица payment_doc с полями customer_id,payment_sum) и тратит(bill и customer_id,bill_amount), следовательно его баланс = разнице между суммами этих величин.

Сейчас при сохранении формы ввода начисления или платежа вызываю функцию типа:

PROCEDURE get_balance
PARAMETERS lnCusomerId

select sum(payment_sum) from payment_doc where customer_id = lnCusomerId into array aPay
select sum(bill_amount) from bill where customer_id = lnCusomerId into array aBill

UPDATE customer set balance = aPay(1,1)+aBill(1,1) where customer_id = customer.customer_id
ENDPROC

Хотелось бы реализовать данную функционал на уровне базы данных.
Попытки вставить функцию в хранимую процедуру и в Rule прописать в таблицах вызов get_balance(customer_id)
для payment_doc и bill ничего не дали. Данные не обновляются. Точнее обновляются предыдущими значениями.

Как обойти? Фокс, к сожалению, не Оракл. :(
...
Рейтинг: 0 / 0
after and before UPDATE триггера
    #37457897
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во-первых, это надо писать не в RULE, а в триггерах. Во всех трех типах INSERT/UPDATE/DELETE. Поскольку RULE - это еще не окончательное значение. Может быть изменено.

Во-вторых, нет никакой необходимости делать запросы. Достаточно из суммы вычесть старое значение платежа и прибавить новое. Триггер все-равно выполняется по одной записи за раз.

Например, триггер для payment_doc будет выглядеть примерно так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
FUNCTION UpdateBalancePayment
* Определяю тип триггера из которого была вызвана данная процедура
LOCAL lcTypeTrigger, lnDelta
DO CASE
CASE Deleted()
	lcTypeTrigger="DELETE"	&& триггер на удаление
	* В триггере на удаление надо вычесть удаляемую сумму
	lnDelta = -OldVal("payment_sum")
CASE NVL(OldVal("Deleted()"),.T.)
	lcTypeTrigger="INSERT"	&& триггер на вставку
	* В триггере на вставку надо добавить вставляемую сумму
	lnDelta = payment_sum
OTHERWISE
	lcTypeTrigger="UPDATE"	&& триггер на модификацию
	* В триггере на модификацию надо вычесть старое значение суммы и добавить новое значение суммы
	lnDelta = payment_sum - OldVal("payment_sum")
ENDCASE

* Собственно модификация суммы баланса, если есть изменения
if m.lnDelta <>  0 
	UPDATE customer set balance = balance + m.lnDelta where customer_id = customer.customer_id
endif

RETURN .T.

Аналогичную функцию надо сделать для триггеров таблицы bill. Можно написать не один общий, а три разных триггера. По их типам.

PS: В триггерах надо с осторожностью использовать алиасы той таблицы, модификация которой и выполняется, поскольку нет никакой гарантии, что алиас таблицы совпадает с ее именем. В данном случае можно использовать функцию Alias(), поскольку, по умолчанию, триггер выполняется в той рабочей области, которая и вызвала срабатывание триггера.

Но можно оставить как есть. Т.е. просто имя поля без указания алиаса. В этом случае предполагается, что речь идет о поле таблицы, открытой в текущей рабочей области. Что, в данном случае, соответствует действительности
...
Рейтинг: 0 / 0
after and before UPDATE триггера
    #37457976
miv32
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Исчерпывающее объяснение. :) Спасибо!
Насчет +/- баланса я тоже думал, но как-то казалось долго.
Триггер на удаление не нужен: не удаляю записи.
Обнуляю суррогатные ключи в таблицах и при добавление новой записи ищу первый попавшийся скажем customer_id = 0 и UPDATE новым ключом + UPDATE полей в таблице.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / after and before UPDATE триггера
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]