简体   繁体   English

Clojure和HugSQL; 如何提供SQL关键字?

[英]Clojure and HugSQL; how to provide SQL keywords?

I have this query defined using HugSQL: 我有使用HugSQL定义此查询:

-- :name ins! :! :n
INSERT INTO table (col0, col1, col2) VALUES :tuple*:values;

How can I send a SQL keyword to this query from Clojure? 如何从Clojure向此查询发送SQL关键字? In particular how could I do something like, 特别是我该怎么做,

(ins! db {:values [[val0 val1 :DEFAULT] [val2 val3 val4]]})

such that the query becomes 这样查询变成

INSERT INTO table (col0, col1, col2) VALUES (val0, val1, DEFAULT), (val2, val3, val4)

That is, how to use the SQL keyword DEFAULT from Clojure? 也就是说,如何使用Clojure的SQL关键字DEFAULT?

Thanks. 谢谢。

PS I'm using clojure.java.jdbc and postgresql. PS我正在使用clojure.java.jdbc和postgresql。

Since the tuple list parameter type (:tuple*) is a value-based parameter type that defers to the underlying jdbc library for parameter replacement, you can't use it to insert raw/keyword sql. 由于元组列表参数类型(:tuple *)是基于值的参数类型,该参数类型依赖于基础jdbc库进行参数替换,因此您不能使用它来插入原始/关键字sql。 This is actually noted here about JDBC's lack of support for this: Sending the DEFAULT placeholder via JDBC? 实际上,这是关于JDBC对此不支持的注释: 通过JDBC发送DEFAULT占位符? .

However, you can use HugSQL's Clojure Expressions to take the :values tuple list and re-write the query to treat Clojure keywords as SQL keywords, and all other values as SQL value parameters. 但是,您可以使用HugSQL的Clojure表达式获取:values元组列表,然后重新编写查询以将Clojure关键字视为SQL关键字,并将所有其他值视为SQL值参数。 Below, we're using HugSQL's Deep Get Param Name feature to reference the value parameters for the given indexes within the tuples. 下面,我们使用HugSQL的Deep Get Param Name功能来引用元组中给定索引的值参数。

-- :name insert-with-default :<!
/* :require [clojure.string :as string] */
insert into test (c1, c2, c3)
values
/*~ 
(string/join ","
  (map-indexed
    (fn [tuple-index tuple]
      (str 
        "(" 
        (string/join ","
          (map-indexed
            (fn [value-index value]
              (if (keyword? value)
                (name value)
                (str 
                  ":v:values." 
                  tuple-index "." 
                  value-index))) 
            tuple))
        ")"))
     (:values params)))
~*/
returning *

Resulting in (assuming 5 is the default value for c3): 结果(假设5是c3的默认值):

(insert-with-default-sqlvec {:values [[1 2 :default]
                                      [3 4 :default]]})

;=> ["insert into test (c1, c2, c3)\n
      values  (?,?,default),(?,?,default) returning *" 1 2 3 4]

(insert-with-default db {:values [[1 2 :default]
                                  [3 4 :default]]})

;=> ({:c1 1, :c2 2, :c3 5} {:c1 3, :c2 4, :c3 5})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM