2

我正在尝试将 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如果输入地址没有指定子网,我不能简单地转换,因为匹配可能会失败。

4

2 回答 2

2

我认为@mu-is-too-short 的答案是更好的解决方法——使用 Postgresql 的强大功能来解决问题。

即便如此,如果您不想为此使用 Postgresql 数组,您可以使用Clojure 表达式为 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 的 deep-get 语法分别拉入每个值并将类型转换添加到每个值。因此,您正在有效地动态构建一组新的 HugSQL 参数,如下所示:

in (:values.0::int, :values.1::int, :values.2::int)

于 2018-07-30T18:49:50.050 回答
2

听起来 HugSQL 正在用:addresses逗号分隔的列表替换,所以你(:addresses::inet)最终看起来像(addr, addr, addr, ..., addr::inet). 如果是这种情况,那么您可以替换in (list)= any(array),使用数组构造函数语法,并将强制转换应用于整个数组:

select * from ip_addresses where address = any(array[:addresses]::inet[])
于 2018-07-26T20:28:31.810 回答