(sql/with-connection {... mydatabase }
(sql/with-query-results rows [ "select * from users where email in (?)"
[ "bob@site.com" "mary@other.com" ] ]
(doseq [rows row]
(prn row))))
这总是不会返回结果。我也尝试过使用“?”代替“(?)”
答案 0 :(得分:2)
AFAIR你不能直接这样做。在场景宏with-query-results
后面使用java.sql.PreparedStatement并为每个参数调用.setObject。所以你必须写这样的东西
(sql/with-connection db
(sql/with-query-results rs
[(str "select * from users where email in ("
(apply
str
(interpose ", " (map #(str "\"" % "\"")
["bob@site.com" "mary@other.com"]))) ")")]
...))
使用“in”参数生成已准备好的sql字符串:"select * from users where email in (\"bob@site.com\", \"mary@other.com\")"
。
更好的方法是使用一个像sqlkorma这样的clojure sql库。
答案 1 :(得分:0)
现在,到2020年,至少在postgres中,您无需字符串即可进行连接。
像这样扩展ISQLParameter协议:
; This allows us to use clojure arrays as query parameters for JDBC.
; Thus, we don't need to do string concatenation to make IN clauses.
(extend-protocol clojure.java.jdbc/ISQLParameter
Sequential
; Important: Sometimes you have to explicitly specify the type of array like ?::text[].
(set-parameter [v ^PreparedStatement stmt ^long i]
(let [conn (.getConnection stmt)
meta (.getParameterMetaData stmt)
type-name (.getParameterTypeName meta i)]
(if-let [elem-type (when (= (first type-name) \_) (apply str (rest type-name)))]
(.setObject stmt i (.createArrayOf conn elem-type (to-array v)))
(.setObject stmt i v)))))
然后您可以运行
之类的查询(jdbc/query db/db ["select 'banana' = ANY(?) as banana_included,
'apple' = ANY(?) as apple_included"
["banana" "potato"] ["banana" "potato"]])
= ANY(array)
语法与in
子句的功能相同-据我所知,IN
子句在postgres内部转换为= ANY(array)
-不引用我的话。