简体   繁体   English

使用Postgres在HugSQL或YesQL中强制转换多个值

[英]Casting Multiple Values in HugSQL or YesQL with Postgres

I'm trying to cast a list of ip addresses to ::inet but only the last element in the list gets converted. 我正在尝试将IP地址列表转换为::inet但是仅转换列表中的最后一个元素。

I've tried the following but nothing seems to work. 我尝试了以下方法,但似乎无济于事。

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)

I can't simply cast the address::text since matches can fail if the input addresses don't have a subnet specified. 我不能简单地转换address::text因为如果输入地址没有指定子网,匹配可能会失败。

Sounds like HugSQL is replacing :addresses with a comma delimited list so your (:addresses::inet) ends up looking like (addr, addr, addr, ..., addr::inet) . 听起来好像HugSQL用逗号分隔的列表替换了:addresses ,所以您的(:addresses::inet)最终看起来像(addr, addr, addr, ..., addr::inet) If that's the case then you could replace in (list) with = any(array) , use the array constructor syntax , and apply a cast to that array as a whole: 如果是这种情况,那么您可以用= any(array)替换in (list) ,使用数组构造函数语法 ,然后对整个数组进行强制转换:

select * from ip_addresses where address = any(array[:addresses]::inet[])

I think the answer from @mu-is-too-short is the better workaround for this--using the power of Postgresql to solve the problem. 我认为@ mu-is-too-short的答案是更好的解决方法-使用Postgresql的功能解决问题。

Even so, if you did not want to use Postgresql arrays for this, you can generate a cast for each value in your vector in HugSQL by using a Clojure Expression : 即使这样,如果您不想为此使用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)))
~*/
)

Which will end up giving you something like this: 最终会给你这样的东西:

(x-sqlvec {:values ["1" "2"]})
;=> ["select * from test where id in (?::int,?::int)" "1" "2"]

So, the above takes the values vector and uses HugSQL's deep-get syntax to pull in each of the values individually and add the type cast to each one. 因此,以上代码采用了值向量,并使用HugSQL的deep-get语法分别提取每个值,并将类型转换添加到每个值。 So, you're effectively building a new set of HugSQL parameters on the fly that looks like: 因此,您正在有效地动态构建一组新的HugSQL参数,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM