Сделал процедуру вывода номеров строк, и обнаружил странное поведение оптимизатора и сортировки

create procedure GET_ROW_NUM(
DUMMY blob = null) -- Нужно указавать в случае union all например, т.к. оптимизатор выполняет запрос 1 раз
returns (
 NUM integer)
as
begin
if (RDB$GET_CONTEXT('USER_TRANSACTION', 'LastSetNum') <> current_timestamp)
    then RDB$SET_CONTEXT('USER_TRANSACTION', 'RowNumber', null);
 NUM = coalesce(RDB$GET_CONTEXT('USER_TRANSACTION', 'RowNumber'), 1);
 RDB$SET_CONTEXT('USER_TRANSACTION', 'RowNumber', NUM + 1);
 RDB$SET_CONTEXT('USER_TRANSACTION', 'LastSetNum', current_timestamp);
 suspend;
end

надеюсь то, что current_timestamp не меняется в рамках одного запроса не изменится в следующих версиях, или как?

использование:

select
 (select NUM from GET_ROW_NUM),
 r.RDB$RELATION_NAME
from RDB$RELATIONS r

странно, но в данном случае процедура выполняется нужное мне кол-во раз

select
 (select NUM from GET_ROW_NUM),
 r.RDB$RELATION_NAME
from RDB$RELATIONS r
union all
select
 (select NUM from GET_ROW_NUM),
 r.RDB$RELATION_NAME
from RDB$RELATIONS r

а в этом случае как и ожидалось - только два раза, решается просто

select
 (select NUM from GET_ROW_NUM(r.RDB$RELATION_NAME)),
 r.RDB$RELATION_NAME
from RDB$RELATIONS r
union all
select
 (select NUM from GET_ROW_NUM(r.RDB$RELATION_NAME)),
 r.RDB$RELATION_NAME
from RDB$RELATIONS r

а вот с сортировкой вообще непонятно, я почему-то думал, что сначала производится формирование массива, его сортировка и вывод, а оказалось что это (select NUM from GET_ROW_NUM) выполняется не 42 раза а 84

select
 (select NUM from GET_ROW_NUM),
 r.RDB$RELATION_NAME
from RDB$RELATIONS r
order by 1 desc

ps.

Firebird SS 2.5.1

Reply via email to