我使用HugSQL定义了这个查询:
-- :name ins! :! :n
INSERT INTO table (col0, col1, col2) VALUES :tuple*:values;
如何从Clojure向此查询发送SQL关键字?特别是我怎么能这样做,
(ins! db {:values [[val0 val1 :DEFAULT] [val2 val3 val4]]})
使查询变为
INSERT INTO table (col0, col1, col2) VALUES (val0, val1, DEFAULT), (val2, val3, val4)
也就是说,如何使用Clojure中的SQL关键字DEFAULT?
感谢。
P.S。我使用的是clojure.java.jdbc和postgresql。
答案 0 :(得分:2)
由于元组列表参数类型(:tuple *)是一个基于值的参数类型,它遵循底层的jdbc库进行参数替换,因此不能使用它来插入raw / keyword sql。这里实际上注意到JDBC缺乏对此的支持:Sending the DEFAULT placeholder via JDBC?。
但是,您可以使用HugSQL的Clojure Expressions获取:values元组列表并重新编写查询以将Clojure关键字视为SQL关键字,将所有其他值视为SQL值参数。下面,我们使用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 *
导致(假设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})