简体   繁体   English

使用Clojure / Hugsql处理nil参数

[英]Handling nil parameters with Clojure/Hugsql

I'm using Hugsql with Clojure to access a Postgresql db. 我正在使用带有Clojure的Hugsql来访问Postgresql数据库。 Several of my database tables have optional columns - for a simple example consider a "users" table with various address columns - address1, address2, city, etc. 我的几个数据库表都有可选列 - 举个简单的例子,考虑一个带有各种地址列的“用户”表 - address1,address2,city等。

When I write the Hugsql query specification for an "update" I don't know which values will be present in the map I pass in. So if I write a query: 当我为“更新”编写Hugsql查询规范时,我不知道我传入的地图中将出现哪些值。所以如果我写一个查询:

-- :name update-user! :! :n
UPDATE users set firstname = :firstname, address1 = :address1 where id = :id

but pass in a user map 但传入用户地图

(update-user! {:id "testuser" :firstname "Bartholamew"})

then an exception is thrown. 然后抛出一个异常。 I'd expect it to create something like 我希望它可以创造类似的东西

UPDATE users SET firstname='Bartholamew', address1=NULL where id='testuser'

I've looked at the Hugsql source - it calls a (validate-parameters) function that throws the exception that I can't see a way around. 我查看了Hugsql源代码 - 它调用了一个(validate-parameters)函数,该函数抛出了我无法看到的异常。 I'm sure I'm missing something obvious: this doesn't seem like an unusual requirement, and I sure don't want to write a distinct SQL query spec for every possible combination of optional columns. 我确定我遗漏了一些明显的东西:这似乎不是一个不寻常的要求,我确定不希望为可选列的每个可能组合编写不同的SQL查询规范。

Is there a way to handle missing parameters that I'm missing? 有没有办法处理我遗漏的缺失参数? Am I abusing the database by having optional columns? 我是否通过使用可选列来滥用数据库?

You can use HugSQL's Clojure Expressions to support conditionally including your desired SQL based on the parameters provided at runtime. 您可以使用HugSQL的Clojure表达式根据运行时提供的参数有条件地支持您所需的SQL。 So, you can write something like this: 所以,你可以这样写:

-- :name update-user! :! :n
UPDATE users SET
id = id
--~ (when (contains? params :firstname) ",firstname = :firstname")
--~ (when (contains? params :address1) ",address1 = :address1")
WHERE id = :id

Note: The id=id is a bit silly here to deal with the commas. 注意: id=id在这里处理逗号有点傻。 You can certainly do something more robust and generic with this example from the HugSQL docs: 你可以使用HugSQL文档中的这个例子做一些更强大和通用的东西:

SQL: 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: Clojure的:

(clj-expr-generic-update db {:table "test"
                             :updates {:name "X"}
                             :id 3})

I'd also encourage you to look at and know what's available in the underlying jdbc library. 我还鼓励您查看并了解底层jdbc库中的可用内容。 HugSQL's default adapter is clojure.java.jdbc, and its update! HugSQL的默认适配器是clojure.java.jdbc,它的update! function has similar functionality. 功能具有类似的功能。

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

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