PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Créer une séquence de caractères sur postgreSQL

Défi accepté;)

Je ne pense pas qu'il y ait un moyen de le faire avec uniquement le mécanisme de séquence PostgreSQL ( 1 ) Mais si vous avez vraiment besoin de quelque chose comme ça (et je suis très intéressé par la raison pour laquelle vous avez besoin de quelque chose comme ça), vous pouvez faire une fonction qui vous renvoie la valeur suivante que vous voulez et la mettre dans un déclencheur.

Par exemple, créez d'abord un tableau :

create table test (test_id varchar);

Utilisez une fonction comme celle-ci ci-dessous

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$;

Attachez la fonction à un trigger avant

create trigger tg_test before insert on test for each row execute procedure next_id_test();

Insérez une valeur qui n'a pas vraiment d'importance (elle sera modifiée de toute façon)

insert into test values ('ttt');

Ensuite, vous pouvez observer que vous avez le bon caractère.

select *
from test;

Je sais que c'est un peu lourd mais je n'en vois pas d'autre.La fonction n'est probablement pas parfaite mais je n'ai pas beaucoup de temps :)

J'espère que ça va t'aider;)