Можно с помощью рекурсивного CTE:
with recursive enum as (
select 1 as n from rdb$database
union all
select (e.n + 1) as n from enum e
where e.n < :MAX_N
)
select n from enum
Максимальное значение параметра
:MAX_N ограничено внутренним лимитом сервера на выполнение рекурсивных запросов (несколько тысяч для FB 2.5).
Приведенный код не настолько бесполезен, как может показаться на первый взгляд. С его помощью можно реализовать поиск свободного идентификатора группы пользователей в таблице GD_USERGROUP:
select
first 1 e.n
from
gd_usergroup g right join (
with recursive enum as (
select 7 as n from rdb$database
union all
select (e.n + 1) as n from enum e
where e.n < 32
)
select
n
from
enum) e on e.n = g.id
where
g.id is null
order by
1
Пусть вас не смущает семерка в качестве начального числа счета — первые шесть групп стандартные и не могут быть удалены из таблицы.
2 комментария:
Вот ещё счётчик от a до b без ограничений:
create procedure enum (a integer, b integer)
returns (n integer)
as
begin
n=a;
while (n <= b) do
begin suspend; n = n + 1; end
end
А вывести первый не использованный id можно как-то так:
execute block ( a integer=: a, b integer=: b)
returns ( n integer, id integer)
as
begin
n=a;
while (n <= b) do
begin
id = 0;
select g.id from gd_usergroup g where g.id = :n into :id;
if (id = 0) then begin suspend; leave; end
n = n + 1;
end
end
Да, можно и так. Но, хотелось обойтись без хранимых процедур и алгоритмической обработки. Т.е. свести все только к SELECT запросу.
Отправить комментарий