Для начала опишу ситуацию
Есть ХП, реализующая начисление абонентской платы абонентам телефонной сети. Она пробегает по всем активным на начало месяца телефонам (используя реквизиты Install_date и Uninstall_date) и по каждому в соответствии с его тарифным планом производит первоначальное начисление базовой абонплаты.
Есть также таблица где регистрируется за какой период уже была начислена абон. плата (там хранится месяц и год всего лишь). При записи каждого звонка а таблицу, срабатвает триггер before insert, в нём происходит обращение к этой таблице и проверяется начислена ли абон. плата за месяц в котором был совершен звонок и если вдруг окажется что АП ещё не была начислена, то выполняется вышеупомянутая ХП и в таблицу закрытых периодов ставится об этом отметка. Всё.
Теперь собстанно ХП:
Код: Выделить всё
CREATE PROCEDURE ABON_PAY_CHARGE (
per_month smallint,
per_year smallint,
last_upd timestamp)
as
declare variable tel_id bigint;
declare variable contr_id bigint;
declare variable tp_code smallint;
declare variable tp_abon_pay numeric(8,2);
declare variable pred_month smallint;
declare variable pred_year smallint;
declare variable last_day date;
begin
/*Делаем отметку о том что за данный период АП начислена*/
insert into closed_periods(p_month, p_year) values (:per_month, :per_year);
/*Получаем год и месяц предыдущего периода, на вход 1,2008 - получим 12,2007*/
select pred_month, pred_year from pred_period(:per_month, :per_year) into :pred_month, :pred_year;
/*получаем последний день предыдущего периода, на вход 12,2007 - получаем 31.12.2007*/
execute procedure end_of_month(:pred_month, :pred_year) returning_values :last_day;
for
/*выбираем все активные по стстоянию на 31.12.2007 телефонные номера..... */
select telephones.id, telephones.contract_id, telephones.tarif_plan_code,
tarif_plan.abon_pay from tarif_plan
inner join telephones on (tarif_plan.id = telephones.tarif_plan_code)
where
((telephones.install_date <= :last_day) and ((telephones.uninstall_date >= :last_day) or (telephones.uninstall_date is null)))
into :tel_id, :contr_id, :tp_code, :tp_abon_pay
do
begin
/*.....и на каждый из них начисляем базовую абон.плату за Январь 2008*/
insert into abon_pay(P_month, p_year, id_telephone, id_contract, tarif_plan_code,
abon_pay_value, abon_pay_result, last_updated) values
(:per_month, :per_year, :tel_id, :contr_id, :tp_code, :tp_abon_pay, :tp_abon_pay, :last_upd);
end
end
Код: Выделить всё
if (not exists(select first 1 id from closed_periods where ((p_month = new.c_month) and (p_year = new.c_year)))) then
execute procedure abon_pay_charge(new.c_month, new.c_year, :last_upd);
Код: Выделить всё
select count(*) from closed_periods where
((p_month = new.c_month) and (p_year = new.c_year))
into :abon_pay_cnt;
if (abon_pay_cnt = 0) then execute procedure abon_pay_charge(new.c_month, new.c_year, :last_upd);
Может кто подскажет почему так? Вроде и тот способ и другой одну процедуру выполняют, а результат разный
P.S. Firebird 2.0.3