Způsoby bez dynamického SQL
text
neobsahuje žádné přetypování z hexadecimálních čísel reprezentaci na číselný typ, ale můžeme použít bit(n)
jako waypoint. Existují nedokumentované přetypuje z bitových řetězců (bit(n)
) na celočíselné typy (int2
, int4
, int8
) - interní reprezentace je binárně kompatibilní. Cituji Toma Lanea:
To se spoléhá na nějaké nezdokumentované chování vstupního převodníku bitového typu, ale nevidím důvod očekávat, že by se to zlomilo. Možná větším problémem je, že vyžaduje PG>=8.3, protože před tím neexistovalo bitové přetypování textu.
integer
pro max. 8 hexadecimálních číslic
Až 8 hexadecimálních číslic lze převést na bit(32)
a poté vynucen na integer
(standardní 4bajtové celé číslo):
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 používá typ celého čísla se znaménkem, takže hexadecimální čísla nad '7fffffff'
přetečení do záporného celého čísla čísla. Toto je stále platná, jedinečná reprezentace, ale význam je jiný. Pokud na tom záleží, přepněte na bigint
; viz níže.
U více než 8 hexadecimálních číslic budou nejméně významné znaky (přesahující vpravo) zkráceny .
4 bity v kódování bitového řetězce 1 hexadecimální číslice . Hexadecimální čísla známé délky lze přetypovat na příslušný bit(n)
přímo. Případně zadejte hexadecimální čísla neznámé délky s úvodními nulami (0
), jak je ukázáno a přetypováno na bit(32)
. Příklad se 7 hexadecimálními číslicemi a int
nebo 8 číslic a bigint
:
SELECT ('x'|| 'deafbee')::bit(28)::int
, ('x'|| 'deadbeef')::bit(32)::bigint;
int4 | int8
-----------+------------
233503726 | 3735928559
bigint
pro max. 16 hexadecimálních číslic
Až 16 hexadecimálních číslic lze převést na bit(64)
a poté vynucen na bigint
(int8
, 8bajtové celé číslo) - v horní polovině opět přetečení do záporných čísel:
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
pro max. 32 hexadecimálních číslic
Postgres uuid
datový typ není číselný typ . Je to však nejefektivnější typ ve standardním Postgresu pro uložení až 32 hexadecimálních číslic, přičemž zabírá pouze 16 bajtů úložiště. Je zde přímé obsazení z text
na uuid
(není potřeba bit(n)
jako waypoint), ale přesně Je vyžadováno 32 hexadecimálních číslic.
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 můžete vidět, standardní výstup je řetězec hexadecimálních číslic s typickými oddělovači pro UUID.
md5 hash
To je zvláště užitečné pro ukládání md5 hash :
SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash;
md5_hash
--------------------------------------
02e10e94-e895-616e-8e23-bb7f8025da42
Viz:
- Jaký je optimální datový typ pro pole MD5?