4

我正在尝试将 WHERE 条件动态添加到 Korma SQL 查询

(-> the-query
    (where {:archived false})
    (add-where-conditions params)
    (limit 200)
    (select))

我正在尝试动态构建对 korma 的where函数的调用。调用看起来像(where query (or (between :freq [100 200]) (between :freq [300 400]) ... )). 辅助函数make-conds列出where函数的参数,例如:(or (between :freq [100 200]) ...

我尝试了以下方法来构建动态 where 调用。只有第一个,有eval作品的。为什么?有一个更好的方法吗?

(defn add-where-conditions [query params]
  (eval (list 'where query (make-conds params))))

(defmacro add-where-conditions-2 [query params]
  (list 'where query (make-conds params))) ; broken

(defmacro add-where-conditions-3 [query params]
  `(where ~query ~(make-conds params))) ; broken

免责声明:我是 Clojure 和 Korma 的新手

4

1 回答 1

1

宏不起作用的原因是在这两种情况下,params参数的值都是 symbol params。这就是为什么在宏add-where-conditions-2进行add-where-conditions-3调用(make-conds params)时,函数接收到的值不是您正在考虑的列表而是符号params,在以下行中显示错误:

IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol  clojure.lang.RT.seqFrom (RT.java:505)

第一种情况有效,因为函数接收列表(不是符号)作为params参数的值,所以eval接收列表(where {:your-query nil} (or (between :freq [100 200]) ,,,)),这是where宏所期望的并且知道如何处理。

where宏解析表达式以搜索它用来构建表达式的一些谓词。where*,功能替代品,没有那种功能,所以我想不出eval吃蛋糕和拥有它的替代品。

于 2013-06-17T20:22:11.197 回答