7

Postgresql dbにアクセスするためにClojureでHugsqlを使用しています。私のデータベース テーブルのいくつかにはオプションの列があります。簡単な例として、address1、address2、city など、さまざまな住所列を持つ「users」テーブルを考えてみます。

「更新」の 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 のソースを見てきました - それは私が回避できない例外をスローする (validate-parameters) 関数を呼び出します。明らかな何かが欠けていると確信しています。これは珍しい要件のようには見えません。オプションの列のすべての可能な組み合わせに対して個別の SQL クエリ仕様を記述したくないことは確かです。

不足しているパラメーターを処理する方法はありますか? オプションの列を持つことでデータベースを悪用していますか?

4

1 に答える 1

11

HugSQL のClojure 式を使用して、実行時に提供されるパラメーターに基づいて、目的の 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 docs のこの例を使用すると、より堅牢で一般的なことを確実に行うことができます。

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

クロージャ:

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

また、基礎となる jdbc ライブラリーで何が利用できるかを調べて理解することをお勧めします。HugSQL のデフォルトのアダプターは clojure.java.jdbc であり、そのupdate!機能には同様の機能があります。

于 2016-11-04T18:20:04.953 に答える