接受挑战 ;)
我认为仅使用 PostgreSQL 序列机制 (1) 没有任何方法可以做到这一点
但是如果你真的需要这样的东西(我对你为什么需要这样的东西很感兴趣),你可以做一个函数来返回你想要的下一个值并将它放入触发器中。
比如先建一个表:
create table test (test_id varchar);
使用下面这样的函数
create or replace function next_id_test()
returns trigger language plpgsql as $function$
begin
with cte_conform_char_list as
(
select val, row_number() over (order by val), lead(val) over (order by val)
from (values ('A'), ('B'), ('C'), ('D'), ('E'), ('F')) as t(val) -- you can continue this list as much as you want it ;)
order by 1
)
, cte_built_char_list as
(
select
cte.val
, cte.row_number
, coalesce(cte.lead, cte_2.val) as next_char
from cte_conform_char_list cte
left outer join cte_conform_char_list cte_2
on cte_2.row_number = cte.row_number - (select max(row_number) from cte_conform_char_list) +1
)
select
case
when row_number < (select max(row_number) from cte_built_char_list)
then repeat(next_char, cast(rank() over (partition by row_number order by test_id) as int))
else repeat(next_char, cast(rank() over (partition by row_number order by test_id) + 1 as int))
end as next_test_id into new.test_id
from test T
inner join cte_built_char_list cte on substring(T.test_id from 1 for 1) = cte.val
order by char_length(test_id), test_id;
return new;
end;
$function$;
将函数附加到前触发器
create trigger tg_test before insert on test for each row execute procedure next_id_test();
插入一个无关紧要的值(无论如何都会改变)
insert into test values ('ttt');
然后你可以观察到你有正确的角色。
select *
from test;
我知道这有点沉重,但我没有看到任何其他方式。
该功能可能并不完美,但我没有很多时间:)
希望对你有所帮助;)