一开始,我对clojure非常陌生。因此,我正试图动态地使用honeysql编写查询:
(:use [honeysql.core :as sql]
[honeysql.helpers :refer :all])
(sql/format {:select [:*] :from [:test]
:where [:or [:= :name "foo"]
[:= :name "bar"]]})
;; ["SELECT * FROM test WHERE (name = ? OR name = ?)" "foo" "bar"]我有函数构建条款:
(defn build-clause [names]
[:or (map #(vector := :name %) names)])
(sql/format {:select [:*]
:from [:test]
:where (build-clause ["foo" "bar"])})
;; ClassCastException clojure.lang.PersistentVector cannot be cast to clojure.lang.Named我认为问题在于构建子句函数的返回。
[:or ([:= :name "foo"] [:= :name "bar"])]我想要这个:
[:or [:= :name "foo"] [:= :name :bar]]我该如何正确地重写build子句?列表展开了吗?
发布于 2013-09-15 21:43:47
您是正确的,map函数是插入一个列表作为第二个元素,而不是按您的意愿插入。
试试这个:
(defn build-clause2 [names]
(into [:or] (map #(vector := :name %) names)))或者:
(defn build-clause2 [names]
(apply conj [:or] (map #(vector := :name %) names)))或者:
(defn build-clause2 [names]
(reduce conj [:or] (map #(vector := :name %) names)))所有这些都会取得同样的结果,所以在这种情况下,更多的是品味问题。
此外,build-clause是honeysql.helpers命名空间中的一个多方法。当您honeysql.helpers :refer :all时,您可以创建一个名称冲突。
发布于 2015-02-01 12:38:47
还有merge-where,它可以用来,嗯,合并其中的字段。它还接受null,这样就可以像这样打包它:
(->
(select :*)
(from :test)
(merge-where (if (> id 0) [:= :id id]))
(merge-where (if-not (nil? src) [:= :src src]))
sql/format)我只是想指出这一点,因为我花了很长时间才弄明白这一点。
https://stackoverflow.com/questions/18817516
复制相似问题