sql >> Database >  >> RDS >> PostgreSQL

Een tekenreeks maken op postgreSQL

Uitdaging geaccepteerd;)

Ik denk niet dat er een manier is om dat te doen met alleen het PostgreSQL-sequentiemechanisme ( 1 )Maar als je zoiets echt nodig hebt (en ik ben best geïnteresseerd in waarom je zoiets nodig hebt), kun je een functie uitvoeren die je de volgende gewenste waarde teruggeeft en deze in een trigger plaatst.

Maak bijvoorbeeld eerst een tabel:

create table test (test_id varchar);

Gebruik een functie zoals deze hieronder

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

Koppel de functie aan een before-trigger

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

Voer een waarde in die er niet echt toe doet (deze wordt hoe dan ook gewijzigd)

insert into test values ('ttt');

Dan kun je zien dat je het juiste karakter hebt.

select *
from test;

Ik weet dat het een beetje zwaar is, maar ik zie geen andere. De functie is waarschijnlijk niet perfect, maar ik heb niet veel tijd :)

Ik hoop dat het je gaat helpen;)




  1. Hoe kan ik A met B en ook B met C tegelijk verbinden?

  2. Wat is dynamische SQL?

  3. Ik probeer een statische databaseklasse te bouwen waartoe ik toegang heb vanuit elke functie buiten de klasse

  4. Hoe een tekenreeks in twee verschillende talen (Hindi/Engels) in php . weer te geven