我正在尝试将IP地址列表转换为::inet
,但仅转换列表中的最后一个元素。
我尝试了以下操作,但似乎无济于事。
select * from ip_addresses where address in (:addresses::inet)
select * from ip_addresses where address in (:addresses)::inet
select * from ip_addresses where address in CAST (:addresses AS inet)
我不能简单地强制转换address::text
,因为如果输入地址未指定子网,则匹配可能会失败。
答案 0 :(得分:1)
类似HugSQL之类的声音正在用逗号分隔列表替换:addresses
,因此您的(:addresses::inet)
最终看起来像(addr, addr, addr, ..., addr::inet)
。如果是这种情况,则可以将in (list)
替换为= any(array)
,使用array constructor syntax,然后对整个数组进行强制转换:
select * from ip_addresses where address = any(array[:addresses]::inet[])
答案 1 :(得分:1)
我认为@ mu-is-too-short的答案是更好的解决方法-使用Postgresql的功能来解决问题。
即使如此,如果您不想为此使用Postgresql数组,也可以使用Clojure Expression来为HugSQL中的向量中的每个值生成一个强制转换:
-- :name x
-- :require [clojure.string :as string]
select * from test where id in (
/*~
(clojure.string/join
","
(map-indexed (fn [i v] (str ":values." i "::int")) (:values params)))
~*/
)
最终会给你这样的东西
(x-sqlvec {:values ["1" "2"]})
;=> ["select * from test where id in (?::int,?::int)" "1" "2"]
因此,上面的方法使用值向量,并使用HugSQL's deep-get syntax分别提取每个值,并将类型转换添加到每个值。因此,您正在有效地动态构建一组新的HugSQL参数,如下所示:
in (:values.0::int, :values.1::int, :values.2::int)