我想将 inet 格式的 IPv4 地址转换为整数组件。
例如,将 '101.255.30.40' 变成 oct1=101, oct2=255, oct3=30, oct4=40。
如果我将 inet 转换为 varchar,则应该使用正则表达式来执行此操作,但这似乎不优雅。是否有用于返回 inet 的第 n 个八位字节的 1 行函数?
select inet_to_octet('101.255.30.40', 4) as temp; -- returns temp=40?
我想将 inet 格式的 IPv4 地址转换为整数组件。
例如,将 '101.255.30.40' 变成 oct1=101, oct2=255, oct3=30, oct4=40。
如果我将 inet 转换为 varchar,则应该使用正则表达式来执行此操作,但这似乎不优雅。是否有用于返回 inet 的第 n 个八位字节的 1 行函数?
select inet_to_octet('101.255.30.40', 4) as temp; -- returns temp=40?
除非您想尝试将函数贡献给 inet 数据类型,否则您需要依赖基于字符串的版本。也许将这样的东西(但有一些错误检查)放入 SQL 函数中以便于访问?:
CREATE OR REPLACE FUNCTION extract_octet(inet, integer) RETURNS integer AS $$
SELECT ((regexp_split_to_array(host($1), E'\\.'))[$2])::int;
$$ LANGUAGE SQL;
select extract_octet(inet '192.26.22.2', 2)
Output: 26
终于从同事那里得到了很好的答案...
对于某些风格的 sql,使用“split_part”和 host(inet) 来获取文本字段。
select split_part(host('101.255.30.40'::inet), '.', 1);
select split_part(host('101.255.30.40'::inet), '.', 2);
select split_part(host('101.255.30.40'::inet), '.', 3);
select split_part(host('101.255.30.40'::inet), '.', 4);
结果是
101
255
30
40
如果您想更复杂地处理 IPv6,请使用掩码来加速操作以及使用 case 语句来获取 IP 版本:
select
(case
when family('101.255.30.40'::inet) = 4 then split_part(host(broadcast(set_masklen('101.255.30.40'::inet, 32))), '.', 4)::varchar
when family('101.255.30.40'::inet) = 6 then split_part(host(broadcast(set_masklen('101.255.30.40'::inet, 64))), ':', 4)::varchar
else null end)::varchar as octet4;
select
(case
when family('2604:8f00:4:80b0:3925:c69c:458:3f7b'::inet) = 4 then split_part(host(broadcast(set_masklen('2604:8f00:4:80b0:3925:c69c:458:3f7b'::inet, 32))), '.', 4)::varchar
when family('2604:8f00:4:80b0:3925:c69c:458:3f7b'::inet) = 6 then split_part(host(broadcast(set_masklen('2604:8f00:4:80b0:3925:c69c:458:3f7b'::inet, 64))), ':', 4)::varchar
else null end)::varchar as octet4;
结果是
40
80b0
如果您想将 IPv6 转换为数字,则可以在 case 语句中添加十六进制到整数的转换。
下面是几个用于 IPv4 地址的单独八位字节的单行代码:
SELECT substring(host('1.2.3.4'::inet) FROM '^([0-9]+)\.[0-9]+\.[0-9]+\.[0-9]+$');
将返回1
SELECT substring(host('1.2.3.4'::inet) FROM '^[0-9]+\.([0-9]+)\.[0-9]+\.[0-9]+$');
将返回2
SELECT substring(host('1.2.3.4'::inet) FROM '^[0-9]+\.[0-9]+\.([0-9]+)\.[0-9]+$');
将返回3
SELECT substring(host('1.2.3.4'::inet) FROM '^[0-9]+\.[0-9]+\.[0-9]+\.([0-9]+)$');
将返回4