使用SQL::Abstract,我需要将IP列类型转换为TEXT,以便能够使用LIKE进行搜索。我只找到了一个“hacky”的方式来实现它:
SQL::Abstract
TEXT
LIKE
where( { ip => { '::TEXT LIKE' => $myParameter } } )
它生成
WHERE ( "ip" ::TEXT LIKE ? )
问题是:有没有一种不那么粗俗或官方的方式来实现这一点?问题不是:
IP
ymdaylpp1#
问题出在Mojo::Pg中,它将"的quote_char添加到SQL::Abstract对象。当我将其设置为空字符串时,它将按预期工作:
Mojo::Pg
"
quote_char
where( { 'ip::TEXT' => { 'LIKE' => $myParameter } } )
但是,为了完整,我不得不使用
where( { 'host(ip)' => { 'LIKE' => $myParameter } } )
因为::TEXT将给予附加了/32的IP。
::TEXT
/32
cx6n0qe32#
我认为你在问题中混淆了很多东西。你让它听起来像是一个SQL::Abstract问题,而你真正的问题是底层SQL本身。首先,我个人会避免在大多数情况下使用SQL::Abstract(有时创建复杂查询非常慢,而且您不能确定它的输出),在您需要非标准的东西的情况下,我也会避免使用SQL::Abstract。那么,继续说下去,我不确定您所说的IP类型是什么意思,从您的postgres标记和提到的CIDR来看,我怀疑您指的是inet类型。如果是这样的话,LIKE的等价物是使用子网掩码,这基本上就是使用inet而不是text/varchar字段的全部原因。例如,对于192.168.*,您可以使用子网斜线表示法执行如下操作:
CIDR
inet
192.168.*
SELECT * FROM users WHERE ip << inet '192.168.0.0/16'
如果您不想将IP视为实际IP并利用上述内容,而是想将其视为文本(例如,您希望搜索192.16%,生成192.168.*结果,但同时搜索192.16.*等,这不是通过子网掩码完成的),则您可以首先使用文本类型,或者如您所说,直接动态转换为使用LIKE:
192.16%
192.16.*
SELECT * FROM users WHERE TEXT(ip) LIKE '192.168.%'
使用子网掩码会对性能造成影响,但这是否会成为一个问题当然取决于您的数据。注意cidr的工作原理与inet类似,它对LIKE没有帮助。
cidr
2条答案
按热度按时间ymdaylpp1#
问题出在
Mojo::Pg
中,它将"
的quote_char
添加到SQL::Abstract对象。当我将其设置为空字符串时,它将按预期工作:
但是,为了完整,我不得不使用
因为
::TEXT
将给予附加了/32
的IP。cx6n0qe32#
我认为你在问题中混淆了很多东西。你让它听起来像是一个
SQL::Abstract
问题,而你真正的问题是底层SQL本身。首先,我个人会避免在大多数情况下使用
SQL::Abstract
(有时创建复杂查询非常慢,而且您不能确定它的输出),在您需要非标准的东西的情况下,我也会避免使用SQL::Abstract
。那么,继续说下去,我不确定您所说的
IP
类型是什么意思,从您的postgres标记和提到的CIDR
来看,我怀疑您指的是inet
类型。如果是这样的话,LIKE
的等价物是使用子网掩码,这基本上就是使用inet
而不是text/varchar字段的全部原因。例如,对于192.168.*
,您可以使用子网斜线表示法执行如下操作:如果您不想将IP视为实际IP并利用上述内容,而是想将其视为文本(例如,您希望搜索
192.16%
,生成192.168.*
结果,但同时搜索192.16.*
等,这不是通过子网掩码完成的),则您可以首先使用文本类型,或者如您所说,直接动态转换为使用LIKE
:使用子网掩码会对性能造成影响,但这是否会成为一个问题当然取决于您的数据。
注意
cidr
的工作原理与inet
类似,它对LIKE
没有帮助。