Sposoby bez dynamicznego SQL
Nie ma rzutowania z liczb szesnastkowych w text
reprezentacja na typ liczbowy, ale możemy użyć bit(n)
jako punkt orientacyjny. Są nieudokumentowane rzutuje z ciągów bitów (bit(n)
) na typy całkowite (int2
, int4
, int8
) - wewnętrzna reprezentacja jest zgodna z binarnymi. Cytując Toma Lane'a:
Opiera się to na pewnym nieudokumentowanym zachowaniu konwertera wejściowego typu bitowego, ale nie widzę powodu, aby oczekiwać, że to się zepsuje. Prawdopodobnie większym problemem jest to, że wymaga PG>=8.3, ponieważ wcześniej nie było tekstu do rzutowania bitów.
integer
dla max. 8 cyfr szesnastkowych
Do 8 cyfr szesnastkowych można przekonwertować na bit(32)
a następnie przekonwertowany na integer
(standardowa 4-bajtowa liczba całkowita):
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 używa liczby całkowitej ze znakiem, więc liczby szesnastkowe powyżej '7fffffff'
przepełnienie do ujemnej liczby całkowitej liczby. Jest to nadal ważne, niepowtarzalne przedstawienie, ale znaczenie jest inny. Jeśli to ma znaczenie, przełącz się na bigint
; patrz poniżej.
W przypadku więcej niż 8 cyfr szesnastkowych najmniej znaczące znaki (nadmiar w prawo) są obcinane .
4 bity w ciągu bitowym zakoduj 1 cyfrę szesnastkową . Liczby szesnastkowe o znanej długości można rzutować na odpowiedni bit(n)
bezpośrednio. Możesz też uzupełnić liczby szesnastkowe o nieznanej długości z wiodącymi zerami (0
) jak zademonstrowano i rzucono na bit(32)
. Przykład z 7 cyframi szesnastkowym i int
lub 8 cyfr i bigint
:
SELECT ('x'|| 'deafbee')::bit(28)::int
, ('x'|| 'deadbeef')::bit(32)::bigint;
int4 | int8
-----------+------------
233503726 | 3735928559
bigint
dla max. 16 cyfr szesnastkowych
Do 16 cyfr szesnastkowych można przekonwertować na bit(64)
a następnie zmuszony do bigint
(int8
, 8-bajtowa liczba całkowita) - przepełnienie na liczby ujemne ponownie w górnej połowie:
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
dla max. 32 cyfry szesnastkowe
Postgres uuid
typ danych nie jest typem liczbowym . Ale jest to najbardziej wydajny typ w standardowym Postgresie, który przechowuje do 32 cyfr szesnastkowych, zajmując tylko 16 bajtów pamięci. Istnieje bezpośrednia obsada z text
do uuid
(nie ma potrzeby używania bit(n)
jako punkt orientacyjny), ale dokładnie Wymagane są 32 cyfry szesnastkowe.
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
Jak widać, standardowe wyjście to ciąg cyfr szesnastkowych z typowymi separatorami dla UUID.
hasz md5
Jest to szczególnie przydatne do przechowywania skrótów md5 :
SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash;
md5_hash
--------------------------------------
02e10e94-e895-616e-8e23-bb7f8025da42
Zobacz:
- Jaki jest optymalny typ danych dla pola MD5?