在Postgres中,是否可以从表中获取所有行,其中列可以转换为不同的类型?

Bry*_*yan 3 postgresql cast where

我在 Postgres 数据库中有一个表TEXT,其中有一列名为data,我用它来存储 IP 地址和域名。我想知道是否可以选择表中data列为有效 IP 地址的所有行。

WHERE可以使用基于类型转换的子句来完成此操作吗?

小智 5

您可以为此创建一个函数:

create function is_valid_ip(p_data text)
  returns boolean
as
$$
begin
  return p_data::inet is not null;
exception 
  when others then return false;
end;
$$
language plpgsql;
Run Code Online (Sandbox Code Playgroud)

此函数的优点是在转换和过滤行时执行相同的验证。

但这会非常慢,因为 PL/pgSQL 中的异常块非常昂贵,并且捕获异常块的成本甚至更高。因此,如果您有大量无效地址,这将非常慢。

您可以像这样使用该函数:

select *
from the_table
where is_valid_ip(address)
Run Code Online (Sandbox Code Playgroud)

另一种选择是为此使用常规异常:

create function is_valid_ip(p_data text)
  returns boolean
as
$$
  select p_data ~ '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}';
$$
language sql;
Run Code Online (Sandbox Code Playgroud)

该函数的执行速度比使用强制转换的函数快得多但其规模有所缩小,因为它使用稍微不同的规则来检查 IP 地址是否有效。正则表达式仅检查 IPv4 地址,因此很可能还希望扩展正则表达式以检查 IPv6 地址(强制转换将自动执行此操作)