Партия велела портировать простенький кусочек из Firebird на Oracle и MSSQL. MSSQL вижу второй раз в жизни.
Выделяя суть, задача выглядит так: есть таблица t c первичным ключем id. Есть функция f, которая очень долго считает свой результат. По этому результату надо регулярно отбирать/сортировать. Самое плохое, что результат функции зависит от текущей даты. С клиента приходит хитросформированный клиентом по своей механике запрос к вьюхе v, c наложеными сверху условиями на поля из группы "всякое-разное" (что предотвращает пересчет всей таблицы, она большая).
соответвенно, в FB выглядело так (это схема, идея):
create table t(
id not null integer primary key,
calcdate date,te
calcresult double precision,
/* всякое-разное */
);
create procedure f(id bigint)
returns (result double precision)
as
begin
select calcdate, calcresult
into :calcdate, :result
from t where id = :id;
if (calcdate != cast('now' as date)) then
begin
/* тут черт ногу сломит */
update t set calcresult = :result, calcdate = cast('now' as date) where id = :id;
end;
suspend;
end;
create view v(id, result, /* всякое-разное */)
as
select
t.id,
(select result from f(t.id)),
/* всякое-разное */
from t;
В оракле я обошелся автономными транзакциями, всё работает нормально. Как бы мне выкрутиться с MSSQL, где у функций
не может быть побочного эффекта? Вариант научить клиента сначала пересчитать то, что нужно, вызвав какую-то процедуру и дав ей условия на всякое-разное, а потом селектить непосредственно из таблицы - довольно кисл, в клиента лезть не хотелось бы
(не по религиозным соображениям, а чтобы его не обновлять, это в наших условиях непросто). Будет мне щастье?
На всякий случай: планируется требовать MSSQL не ниже 2005, но если есть решение только для 2008 - буду всё равно очень благода.