PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Преобразувайте шестнадесетичен в текстово представяне в десетично число

Начини без динамичен SQL

В text няма прехвърляне от шестнадесетични числа представяне до числов тип, но можем да използваме bit(n) като пътна точка. Иманедокументирани предава от битови низове (bit(n) ) към целочислени типове (int2 , int4 , int8 ) - вътрешното представяне е двоично съвместимо. Цитирам Том Лейн:

Това разчита на някакво недокументирано поведение на преобразувателя на входен тип бит, но не виждам причина да очаквам, че това ще се счупи. Вероятно по-голям проблем е, че изисква PG>=8.3, тъй като преди това не е имало прехвърляне на текст към битове.

integer за макс. 8 шестнадесетични цифри

До 8 шестнадесетични цифри могат да бъдат преобразувани в bit(32) и след това принуден към integer (стандартно 4-байтово цяло число):

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 използва подписан тип цяло число, така че шестнадесетичните числа над '7fffffff' преливане в отрицателно цяло число числа. Това все още е валидно, уникално представяне, но значението е различен. Ако това има значение, превключете към bigint; вижте по-долу.

За повече от 8 шестнадесетични цифри най-малко значимите знаци (излишни вдясно) се съкратяват .

4 бита в битов низ кодира 1 шестнадесетична цифра . Шестнадесетични числа с известна дължина могат да бъдат прехвърлени към съответния bit(n) директно. Като алтернатива, въведете шестнадесетични числа с неизвестна дължина с водещи нули (0 ) както е демонстрирано и прехвърлено към bit(32) . Пример със 7 шестнадесетични цифри и int или 8 цифри и bigint :

SELECT ('x'|| 'deafbee')::bit(28)::int
     , ('x'|| 'deadbeef')::bit(32)::bigint;
  int4     | int8
-----------+------------
 233503726 | 3735928559

bigint за макс. 16 шестнадесетични цифри

До 16 шестнадесетични цифри могат да бъдат преобразувани в bit(64) и след това принуден да bigint (int8 , 8-байтово цяло число) - отново преливане в отрицателни числа в горната половина:

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 за макс. 32 шестнадесетични цифри

Postgres uuid типът данни не е числов тип . Но това е най-ефективният тип в стандартния Postgres за съхраняване на до 32 шестнадесетични цифри, заемащи само 16 байта място за съхранение. Имадиректно предаване от text към uuid (няма нужда от bit(n) като точка), но точно Необходими са 32 шестнадесетични цифри.

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

Както можете да видите, стандартният изход е низ от шестнадесетични цифри с типични разделители за UUID.

md5 хеш

Това е особено полезно за съхраняване на md5 хешове :

SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash;
           md5_hash
--------------------------------------
 02e10e94-e895-616e-8e23-bb7f8025da42

Вижте:

  • Кой е оптималният тип данни за поле MD5?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Най-добрият начин да изтриете милиони редове по ID

  2. Външен ключ към една от многото таблици?

  3. PostgreSQL параметризиран Order By / Limit във функцията на таблицата

  4. Търсене на пълен текст в Postgres или CouchDB?

  5. Как да използвам PostgreSQL JSON(B) оператори, съдържащи въпросителен знак? чрез JDBC