使用 Clojure/Hugsql 处理 nil 参数
Handling nil parameters with Clojure/Hugsql
我正在使用 Hugsql 和 Clojure 来访问 Postgresql 数据库。我的几个数据库 tables 有可选的列——举一个简单的例子,考虑一个 "users" table 和不同的地址列——address1、address2、city 等。
当我为 "update" 编写 Hugsql 查询规范时,我不知道传入的映射中会出现哪些值。因此,如果我编写查询:
-- :name update-user! :! :n
UPDATE users set firstname = :firstname, address1 = :address1 where id = :id
但传入用户地图
(update-user! {:id "testuser" :firstname "Bartholamew"})
然后抛出异常。我希望它能创建类似
的东西
UPDATE users SET firstname='Bartholamew', address1=NULL where id='testuser'
我查看了 Hugsql 源代码 - 它调用了一个(验证参数)函数,该函数抛出了我无法解决的异常。我确定我遗漏了一些明显的东西:这似乎不是一个不寻常的要求,而且我肯定不想为可选列的每种可能组合编写不同的 SQL 查询规范。
有没有办法处理我遗漏的参数?我是否通过使用可选列来滥用数据库?
您可以使用 HugSQL 的 Clojure Expressions 支持根据运行时提供的参数有条件地包含您想要的 SQL。所以,你可以这样写:
-- :name update-user! :! :n
UPDATE users SET
id = id
--~ (when (contains? params :firstname) ",firstname = :firstname")
--~ (when (contains? params :address1) ",address1 = :address1")
WHERE id = :id
注意:id=id
在这里处理逗号有点傻。你当然可以用 HugSQL 文档中的这个例子做一些更健壮和通用的事情:
SQL:
-- :name clj-expr-generic-update :! :n
/* :require [clojure.string :as string]
[hugsql.parameters :refer [identifier-param-quote]] */
update :i:table set
/*~
(string/join ","
(for [[field _] (:updates params)]
(str (identifier-param-quote (name field) options)
" = :v:updates." (name field))))
~*/
where id = :id
Clojure:
(clj-expr-generic-update db {:table "test"
:updates {:name "X"}
:id 3})
我还鼓励您查看并了解基础 jdbc 库中的可用内容。 HugSQL的默认适配器是clojure.java.jdbc,它的update!
函数也有类似的功能。
我正在使用 Hugsql 和 Clojure 来访问 Postgresql 数据库。我的几个数据库 tables 有可选的列——举一个简单的例子,考虑一个 "users" table 和不同的地址列——address1、address2、city 等。
当我为 "update" 编写 Hugsql 查询规范时,我不知道传入的映射中会出现哪些值。因此,如果我编写查询:
-- :name update-user! :! :n
UPDATE users set firstname = :firstname, address1 = :address1 where id = :id
但传入用户地图
(update-user! {:id "testuser" :firstname "Bartholamew"})
然后抛出异常。我希望它能创建类似
的东西UPDATE users SET firstname='Bartholamew', address1=NULL where id='testuser'
我查看了 Hugsql 源代码 - 它调用了一个(验证参数)函数,该函数抛出了我无法解决的异常。我确定我遗漏了一些明显的东西:这似乎不是一个不寻常的要求,而且我肯定不想为可选列的每种可能组合编写不同的 SQL 查询规范。
有没有办法处理我遗漏的参数?我是否通过使用可选列来滥用数据库?
您可以使用 HugSQL 的 Clojure Expressions 支持根据运行时提供的参数有条件地包含您想要的 SQL。所以,你可以这样写:
-- :name update-user! :! :n
UPDATE users SET
id = id
--~ (when (contains? params :firstname) ",firstname = :firstname")
--~ (when (contains? params :address1) ",address1 = :address1")
WHERE id = :id
注意:id=id
在这里处理逗号有点傻。你当然可以用 HugSQL 文档中的这个例子做一些更健壮和通用的事情:
SQL:
-- :name clj-expr-generic-update :! :n
/* :require [clojure.string :as string]
[hugsql.parameters :refer [identifier-param-quote]] */
update :i:table set
/*~
(string/join ","
(for [[field _] (:updates params)]
(str (identifier-param-quote (name field) options)
" = :v:updates." (name field))))
~*/
where id = :id
Clojure:
(clj-expr-generic-update db {:table "test"
:updates {:name "X"}
:id 3})
我还鼓励您查看并了解基础 jdbc 库中的可用内容。 HugSQL的默认适配器是clojure.java.jdbc,它的update!
函数也有类似的功能。