PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Erstellen einer Zeichenfolge auf postgreSQL

Herausforderung angenommen;)

Ich glaube nicht, dass es eine Möglichkeit gibt, dies nur mit dem PostgreSQL-Sequenzmechanismus zu tun (). 1 )Aber wenn Sie so etwas wirklich brauchen (und ich bin sehr daran interessiert, warum Sie so etwas brauchen), können Sie eine Funktion ausführen, die Ihnen den nächsten gewünschten Wert zurückgibt und ihn in einen Trigger einfügt.

Erstellen Sie zum Beispiel zuerst eine Tabelle:

create table test (test_id varchar);

Verwenden Sie eine Funktion wie diese unten

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

Hängen Sie die Funktion an einen Before-Trigger an

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

Geben Sie einen Wert ein, der nicht wirklich wichtig ist (er wird sowieso geändert)

insert into test values ('ttt');

Dann können Sie feststellen, dass Sie den richtigen Charakter haben.

select *
from test;

Ich weiß, das ist ein etwas schwerer Weg, aber ich sehe keinen anderen. Die Funktion ist wahrscheinlich nicht perfekt, aber ich habe nicht viel Zeit :)

Hoffe es wird dir helfen;)