sql >> Database teknologi >  >> RDS >> PostgreSQL

Oprettelse af en tegnsekvens på postgreSQL

Udfordring accepteret;)

Jeg tror ikke, der er nogen måde at gøre det på med kun PostgreSQL-sekvensmekanisme ( 1 )Men hvis du virkelig har brug for sådan noget (og jeg er ret interesseret i, hvorfor du har brug for sådan noget), kan du lave en funktion, der returnerer den næste værdi, du ønsker, og sætter den i en trigger.

Opret f.eks. først en tabel :

create table test (test_id varchar);

Brug en funktion som denne nedenfor

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

Tilslut funktionen til en før-trigger

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

Indsæt en værdi, der ikke rigtig betyder noget (den ændres alligevel)

insert into test values ('ttt');

Så kan du se, at du har den rigtige karakter.

select *
from test;

Jeg ved, det er en lidt tung måde, men jeg kan ikke se nogen anden. Funktionen er nok ikke perfekt, men jeg har ikke meget tid :)

Håber det vil hjælpe dig;)




  1. Mysql:konvertering af dato fra 'dd/mm/åååå' til 'ååååmmdd'

  2. Sådan forbedrer du forespørgselsydeevne med ordre efter, grupper efter og joinforbindelser

  3. Hvordan kan vi omdøbe databasenavnet i MySQL 5.0

  4. Gem accenter i MySQL-databasen