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

Hex in Textdarstellung in Dezimalzahl umwandeln

Wege ohne dynamisches SQL

Es gibt keine Umwandlung von Hex-Zahlen in text Darstellung in einen numerischen Typ, aber wir können bit(n) verwenden als Wegpunkt. Es gibt undokumentierte Umwandlungen von Bitfolgen (bit(n) ) in Integer-Typen (int2 , int4 , int8 ) - die interne Darstellung ist binärkompatibel. Zitat von Tom Lane:

Dies beruht auf einem undokumentierten Verhalten des Bit-Typ-Eingabekonverters, aber ich sehe keinen Grund zu der Annahme, dass dies brechen würde. Ein möglicherweise größeres Problem ist, dass es PG>=8.3 erfordert, da es davor keine Text-to-Bit-Umwandlung gab.

integer für max. 8 Hexadezimalziffern

Bis zu 8 Hexadezimalziffern können in bit(32) umgewandelt werden und dann zu integer gezwungen (standardmäßige 4-Byte-Ganzzahl):

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 verwendet einen vorzeichenbehafteten Integer-Typ, also Hexadezimalzahlen über '7fffffff' Überlauf in negative Ganzzahl Zahlen. Dies ist immer noch eine gültige, eindeutige Darstellung, aber die Bedeutung ist anders. Wenn das wichtig ist, wechseln Sie zu bigint; siehe unten.

Bei mehr als 8 Hexadezimalziffern werden die niederwertigsten Zeichen (Überschuss rechts) abgeschnitten .

4 Bit codieren Sie in einer Bitfolge 1 Hexadezimalziffer . Hex-Zahlen bekannter Länge können auf das jeweilige bit(n) gecastet werden direkt. Füllen Sie alternativ Hexadezimalzahlen unbekannter Länge auf mit führenden Nullen (0 ) wie gezeigt und in bit(32) umgewandelt . Beispiel mit 7 Hex-Ziffern und int oder 8 Ziffern und bigint :

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

bigint für max. 16 Hexadezimalziffern

Bis zu 16 Hexadezimalziffern können in bit(64) umgewandelt werden und dann zu bigint gezwungen (int8 , 8-Byte Integer) - in der oberen Hälfte wieder in negative Zahlen überlaufend:

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 für max. 32 Hexadezimalziffern

Die Postgres-uuid Datentyp ist kein numerischer Typ . Aber es ist der effizienteste Typ in Standard-Postgres, um bis zu 32 Hexadezimalziffern zu speichern und nur 16 Byte Speicherplatz zu belegen. Es gibt eine Direktbesetzung aus text zu uuid (keine Notwendigkeit für bit(n) als Wegpunkt), sondern genau 32 Hexadezimalziffern sind erforderlich.

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

Wie Sie sehen können, ist die Standardausgabe eine Zeichenfolge aus Hexadezimalziffern mit typischen Trennzeichen für UUID.

md5-Hash

Dies ist besonders nützlich, um md5-Hashes zu speichern :

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

Siehe:

  • Was ist der optimale Datentyp für ein MD5-Feld?