因此,我在一个表列上引用了此序列,每次我执行插入操作时,其值都由nextval('ptable_pr_codigo_seq'::regclass)
CREATE SEQUENCE public.ptable_pr_codigo_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 103
CACHE 1;
ALTER TABLE public.ptable_pr_codigo_seq
OWNER TO postgres;
现在,我该如何创建一个新序列,以便每次插入时该值不是数字而是[A〜ZZZ]范围内的字符?。
Example: First insert column value = A
Second = B
Third = C
27th = AA
...
?Th = ZZZ
答案 0 :(得分:0)
接受挑战;)
我认为只有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;
我知道这有点麻烦,但我看不到其他任何方法。 该功能可能并不完美,但我没有很多时间:)
希望它会对您有所帮助;)