Méthodes sans SQL dynamique
Il n'y a pas de cast à partir de nombres hexadécimaux dans text
représentation à un type numérique, mais nous pouvons utiliser bit(n)
comme point de cheminement. Il y a des sans papiers convertit à partir de chaînes de bits (bit(n)
) aux types entiers (int2
, int4
, int8
) - la représentation interne est compatible binaire. Citant Tom Lane :
Cela repose sur un comportement non documenté du convertisseur d'entrée de type bit, mais je ne vois aucune raison de s'attendre à ce que cela se casse. Un problème peut-être plus important est qu'il nécessite PG>=8.3 car il n'y avait pas de textto bit cast avant cela.
integer
pour max. 8 chiffres hexadécimaux
Jusqu'à 8 chiffres hexadécimaux peuvent être convertis en bit(32)
puis converti en integer
(entier standard de 4 octets) :
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 utilise un type entier signé, donc les nombres hexadécimaux au-dessus de '7fffffff'
débordement en entier négatif Nombres. Il s'agit toujours d'une représentation unique et valide, mais la signification est différent. Si cela compte, passez à bigint
; voir ci-dessous.
Pour plus de 8 chiffres hexadécimaux, les caractères les moins significatifs (en excès à droite) sont tronqués .
4 bits dans une chaîne binaire encoder 1 chiffre hexadécimal . Les nombres hexadécimaux de longueur connue peuvent être convertis en bit(n)
respectif directement. Vous pouvez également remplir les numéros hexadécimaux de longueur inconnue avec des zéros non significatifs (0
) comme démontré et converti en bit(32)
. Exemple avec 7 chiffres hexadécimaux et int
ou 8 chiffres et bigint
:
SELECT ('x'|| 'deafbee')::bit(28)::int
, ('x'|| 'deadbeef')::bit(32)::bigint;
int4 | int8
-----------+------------
233503726 | 3735928559
bigint
pour max. 16 chiffres hexadécimaux
Jusqu'à 16 chiffres hexadécimaux peuvent être convertis en bit(64)
puis contraint à bigint
(int8
, entier de 8 octets) - débordant à nouveau en nombres négatifs dans la moitié supérieure :
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
pour max. 32 chiffres hexadécimaux
L'uuid
de Postgres le type de données n'est pas un type numérique . Mais c'est le type le plus efficace dans Postgres standard pour stocker jusqu'à 32 chiffres hexadécimaux, n'occupant que 16 octets de stockage. Il y a une distribution directe à partir de text
en uuid
(pas besoin de bit(n)
comme waypoint), mais exactement 32 chiffres hexadécimaux sont requis.
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
Comme vous pouvez le voir, la sortie standard est une chaîne de chiffres hexadécimaux avec des séparateurs typiques pour UUID.
hachage md5
Ceci est particulièrement utile pour stocker les hachages md5 :
SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash;
md5_hash
--------------------------------------
02e10e94-e895-616e-8e23-bb7f8025da42
Voir :
- Quel est le type de données optimal pour un champ MD5 ?