首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >组合clojure蜂蜜honeysql子句

组合clojure蜂蜜honeysql子句
EN

Stack Overflow用户
提问于 2013-09-15 21:09:10
回答 2查看 1.9K关注 0票数 7

一开始,我对clojure非常陌生。因此,我正试图动态地使用honeysql编写查询:

代码语言:javascript
复制
(: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"]

我有函数构建条款:

代码语言:javascript
复制
(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

我认为问题在于构建子句函数的返回。

代码语言:javascript
复制
[:or ([:= :name "foo"] [:= :name "bar"])]

我想要这个:

代码语言:javascript
复制
[:or [:= :name "foo"] [:= :name :bar]]

我该如何正确地重写build子句?列表展开了吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-15 21:43:47

您是正确的,map函数是插入一个列表作为第二个元素,而不是按您的意愿插入。

试试这个:

代码语言:javascript
复制
(defn build-clause2 [names]
  (into [:or] (map #(vector := :name %) names)))

或者:

代码语言:javascript
复制
(defn build-clause2 [names]
  (apply conj [:or] (map #(vector := :name %) names)))

或者:

代码语言:javascript
复制
(defn build-clause2 [names]
  (reduce conj [:or] (map #(vector := :name %) names)))

所有这些都会取得同样的结果,所以在这种情况下,更多的是品味问题。

此外,build-clausehoneysql.helpers命名空间中的一个多方法。当您honeysql.helpers :refer :all时,您可以创建一个名称冲突。

票数 8
EN

Stack Overflow用户

发布于 2015-02-01 12:38:47

还有merge-where,它可以用来,嗯,合并其中的字段。它还接受null,这样就可以像这样打包它:

代码语言:javascript
复制
(->
  (select :*)
  (from :test)
  (merge-where (if (> id 0) [:= :id id]))
  (merge-where (if-not (nil? src) [:= :src src]))
  sql/format)

我只是想指出这一点,因为我花了很长时间才弄明白这一点。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18817516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档