Fork me on GitHub
#honeysql
<
2022-11-19
>
kotlenik20:11:14

Hi guys! I have had and issue writing simple query to fetch records based on primary keys given in vector to get something like this SELECT * FROM s_lab_results WHERE key IN (23, 456, 890)

kotlenik20:11:46

I have started with query building function as:

(defn records-for-keys-alt
  [table-name primary-key-column records-keys]
  (let [table-name-for-hsql (keyword table-name)
        primary-key-hsql (keyword primary-key-column)]
    (first (hsql/format {:select [:*]
                         :from   [table-name-for-hsql]
                         :where  [:in primary-key-hsql :?values]}
                        {:params {:values records-keys}
                         :pretty true
                         :inline true}))))

kotlenik20:11:25

but it has resulted with : "\nSELECT *\nFROM s_lab_results\nWHERE key IN [23, 456, 890]\n" which is not correct due to usage of [] brackets.

kotlenik20:11:07

What was working after colleague had helped me was:

(defn records-for-keys
  [table-name primary-key-column records-keys]
  (let [table-name-for-hsql (keyword table-name)
        primary-key-hsql (keyword primary-key-column)
        records-keys-inline (mapv #(vector :inline %) records-keys)]
    (first (hsql/format {:select [:*]
                         :from   [table-name-for-hsql]
                         :where  [:in primary-key-hsql records-keys-inline]}
                        {:pretty true}))))
which gives: "\nSELECT *\nFROM s_lab_results\nWHERE key IN (23, 456, 890)\n" but I am not sure where I have made error in initial function. What do you think?

seancorfield21:11:50

The documentation explains why you can't do that (named parameter vector with :in). And that second example isn't safe either. Why are you inlining values? That's not safe in general (SQL injection risks)

kotlenik21:11:42

Understood, thanks! Values are collection of integers. Actual call may be like (q/records-for-keys-alt "s_lab_results" "key" [23 456 890])

kotlenik21:11:03

Integers are always checked, since they are results of diff between source and destination database in data integration mechanism.