perl SQL::抽象类型转换列

rm5edbpk  于 2022-11-24  发布在  Perl
关注(0)|答案(2)|浏览(152)

使用SQL::Abstract,我需要将IP列类型转换为TEXT,以便能够使用LIKE进行搜索。
我只找到了一个“hacky”的方式来实现它:

where( { ip => { '::TEXT LIKE' => $myParameter } } )

它生成

WHERE ( "ip" ::TEXT LIKE ? )

问题是:有没有一种不那么粗俗或官方的方式来实现这一点?
问题不是:

  • 性能会不会差?
  • 我应该使用TEXT列而不是IP列吗?
  • 使用CIDR搜索是否是更好的替代方法
ymdaylpp

ymdaylpp1#

问题出在Mojo::Pg中,它将"quote_char添加到SQL::Abstract对象。
当我将其设置为空字符串时,它将按预期工作:

where( { 'ip::TEXT' => { 'LIKE' => $myParameter } } )

但是,为了完整,我不得不使用

where( { 'host(ip)' => { 'LIKE' => $myParameter } } )

因为::TEXT将给予附加了/32的IP。

cx6n0qe3

cx6n0qe32#

我认为你在问题中混淆了很多东西。你让它听起来像是一个SQL::Abstract问题,而你真正的问题是底层SQL本身。
首先,我个人会避免在大多数情况下使用SQL::Abstract(有时创建复杂查询非常慢,而且您不能确定它的输出),在您需要非标准的东西的情况下,我也会避免使用SQL::Abstract
那么,继续说下去,我不确定您所说的IP类型是什么意思,从您的postgres标记和提到的CIDR来看,我怀疑您指的是inet类型。如果是这样的话,LIKE的等价物是使用子网掩码,这基本上就是使用inet而不是text/varchar字段的全部原因。例如,对于192.168.*,您可以使用子网斜线表示法执行如下操作:

SELECT * FROM users WHERE ip << inet '192.168.0.0/16'

如果您不想将IP视为实际IP并利用上述内容,而是想将其视为文本(例如,您希望搜索192.16%,生成192.168.*结果,但同时搜索192.16.*等,这不是通过子网掩码完成的),则您可以首先使用文本类型,或者如您所说,直接动态转换为使用LIKE

SELECT * FROM users WHERE TEXT(ip) LIKE '192.168.%'

使用子网掩码会对性能造成影响,但这是否会成为一个问题当然取决于您的数据。
注意cidr的工作原理与inet类似,它对LIKE没有帮助。

相关问题