PostgreSQL: существует ли функция, которая преобразует int base-10 в строку base-36? - PullRequest
8 голосов
/ 14 мая 2011

Есть ли в PostgreSQL функция, которая может преобразовать число 10, например 30, в представление 36, например u?

Ответы [ 2 ]

13 голосов
/ 14 мая 2011

Есть функции base-64 (такие как encode), но ничего не для base-36.Но вы могли бы написать свой собственный или использовать этот (обратите внимание, что эта ссылка мертва, я оставлю ее, поскольку это единственное указание, которое у меня есть):

CREATE OR REPLACE FUNCTION base36_encode(IN digits bigint, IN min_width int = 0) RETURNS varchar AS $$
DECLARE
    chars char[]; 
    ret varchar; 
    val bigint; 
BEGIN
    chars := ARRAY['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'  
    ];
    val := digits; 
    ret := ''; 
    IF val < 0 THEN 
        val := val * -1; 
    END IF; 
    WHILE val != 0 LOOP 
        ret := chars[(val % 36)+1] || ret; 
        val := val / 36; 
    END LOOP;

    IF min_width > 0 AND char_length(ret) < min_width THEN 
        ret := lpad(ret, min_width, '0'); 
    END IF;

    RETURN ret;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

Я думаю, вы должны спросить себя, является ли база данных подходящим местом для работы с такого рода форматированием данных, хотя такие проблемы с презентацией лучше решать ближе к конечному уровню просмотра вашего стека.

1 голос
/ 23 мая 2018

вот версия, которая может принимать числа любого размера, она использует тип данных «числовой», который является реализацией postgresql для bignum.

CREATE OR REPLACE FUNCTION base36_encode(IN digits numeric, IN min_width int = 0) RETURNS text AS $$
DECLARE
    chars char[] := ARRAY['0','1','2','3','4','5','6','7','8','9','A','B'
                         ,'C','D','E','F','G','H','I','J','K','L','M','N'
                         ,'O','P','Q','R','S','T','U','V','W','X','Y','Z' ] ;  
    ret text:=''; 
    val numeric:= digits; 
BEGIN
    IF digits < 0 THEN 
        val := -val;
    END IF; 

    WHILE val > 0 OR min_width > 0 LOOP 
        ret := chars[(mod(val,36))+1] || ret; 
        val := div(val,36); 
        min_width := min_width-1;
    END LOOP;
    IF digits < 0 THEN 
        ret := '-'||ret; 
    END IF; 
    RETURN ret;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...