Приведение нескольких значений в HugSQL или YesQL с помощью Postgres
Я пытаюсь составить список 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
поскольку совпадения могут быть неудачными, если во входных адресах не указана подсеть.
2 ответа
Похоже, HugSQL заменяет :addresses
со списком через запятую, так что ваш (:addresses::inet)
в конечном итоге выглядит как (addr, addr, addr, ..., addr::inet)
, Если это так, то вы могли бы заменить in (list)
с = any(array)
используйте синтаксис конструктора массива и примените приведение к этому массиву в целом:
select * from ip_addresses where address = any(array[:addresses]::inet[])
Я думаю, что ответ от @mu-is-too-short - лучший обходной путь для этого - использование возможностей Postgresql для решения проблемы.
Тем не менее, если вы не хотите использовать для этого массивы Postgresql, вы можете сгенерировать приведение для каждого значения вашего вектора в HugSQL, используя выражение Clojure:
-- :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 для извлечения каждого из значений в отдельности и добавления приведения типов к каждому из них. Итак, вы эффективно создаете новый набор параметров HugSQL на лету, который выглядит следующим образом:
in (:values.0::int, :values.1::int, :values.2::int)