4

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?
4

3 に答える 3

3

最後に、同僚から素晴らしい回答をもらいました...

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 を数値としてキャストする場合は、16 進数から整数への変換を case ステートメントに追加できます。

于 2014-01-24T19:09:36.517 に答える