PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Converter hexadecimal na representação de texto em número decimal

Maneiras sem SQL dinâmico


Não há conversão de números hexadecimais em text representação para um tipo numérico, mas podemos usar bit(n) como ponto de passagem. Existem não documentados casts de strings de bits (bit(n) ) para tipos inteiros (int2 , int4 , int8 ) - a representação interna é compatível com o binário. Citando Tom Lane:

Isso depende de algum comportamento não documentado do conversor de entrada do tipo bit, mas não vejo motivo para esperar que isso ocorra. Um problema possivelmente maior é que ele requer PG>=8.3, já que não havia um texto para bit convertido antes disso.

integer para máx. 8 dígitos hexadecimais


Até 8 dígitos hexadecimais podem ser convertidos em bit(32) e, em seguida, forçado a integer (inteiro padrão de 4 bytes):
SELECT ('x' || lpad(hex, 8, '0'))::bit(32)::int AS int_val
FROM  (
   VALUES
      ('1'::text)
    , ('f')
    , ('100')
    , ('7fffffff')
    , ('80000000')     -- overflow into negative number
    , ('deadbeef')
    , ('ffffffff')
    , ('ffffffff123')  -- too long
   ) AS t(hex);
   int_val
------------
          1
         15
        256
 2147483647
-2147483648
 -559038737
         -1

Postgres usa um tipo de inteiro assinado, então números hexadecimais acima de '7fffffff' estouro em inteiro negativo números. Esta ainda é uma representação válida e única, mas o significado é diferente. Se isso for importante, mude para bigint; ver abaixo.

Para mais de 8 dígitos hexadecimais, os caracteres menos significativos (excesso à direita) são truncados .

4 bits em uma string de bits codificar 1 dígito hexadecimal . Números hexadecimais de comprimento conhecido podem ser convertidos para o respectivo bit(n) diretamente. Como alternativa, insira números hexadecimais de comprimento desconhecido com zeros à esquerda (0 ) conforme demonstrado e convertido para bit(32) . Exemplo com 7 dígitos hexadecimais e int ou 8 dígitos e bigint :
SELECT ('x'|| 'deafbee')::bit(28)::int
     , ('x'|| 'deadbeef')::bit(32)::bigint;
  int4     | int8
-----------+------------
 233503726 | 3735928559

bigint para máx. 16 dígitos hexadecimais


Até 16 dígitos hexadecimais podem ser convertidos em bit(64) e, em seguida, forçado a bigint (int8 , inteiro de 8 bytes) - transbordando para números negativos na metade superior novamente:
SELECT ('x' || lpad(hex, 16, '0'))::bit(64)::bigint AS int8_val
FROM  (
   VALUES
      ('ff'::text)
    , ('7fffffff')
    , ('80000000')
    , ('deadbeef')
    , ('7fffffffffffffff')
    , ('8000000000000000')     -- overflow into negative number
    , ('ffffffffffffffff')
    , ('ffffffffffffffff123')  -- too long
   ) t(hex);
       int8_val
---------------------
                 255
          2147483647
          2147483648
          3735928559
 9223372036854775807
-9223372036854775808
                  -1
                  -1

uuid para máx. 32 dígitos hexadecimais


O uuid do Postgres o tipo de dados não é um tipo numérico . Mas é o tipo mais eficiente no Postgres padrão para armazenar até 32 dígitos hexadecimais, ocupando apenas 16 bytes de armazenamento. Há um lançamento direto de text para uuid (sem necessidade de bit(n) como waypoint), mas exatamente São necessários 32 dígitos hexadecimais.
SELECT lpad(hex, 32, '0')::uuid AS uuid_val
FROM  (
   VALUES ('ff'::text)
        , ('deadbeef')
        , ('ffffffffffffffff')
        , ('ffffffffffffffffffffffffffffffff')
        , ('ffffffffffffffffffffffffffffffff123') -- too long
   ) t(hex);
              uuid_val
--------------------------------------
 00000000-0000-0000-0000-0000000000ff
 00000000-0000-0000-0000-0000deadbeef
 00000000-0000-0000-ffff-ffffffffffff
 ffffffff-ffff-ffff-ffff-ffffffffffff
 ffffffff-ffff-ffff-ffff-ffffffffffff

Como você pode ver, a saída padrão é uma sequência de dígitos hexadecimais com separadores típicos para UUID.

md5 hash


Isso é particularmente útil para armazenar md5 hashes :
SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash;
           md5_hash
--------------------------------------
 02e10e94-e895-616e-8e23-bb7f8025da42

Ver:
  • Qual ​​é o tipo de dados ideal para um campo MD5?