Skip to content

Commit

Permalink
fix #268 by clarifying insert-multi! docs
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Corfield <[email protected]>
  • Loading branch information
seancorfield committed Dec 24, 2023
1 parent da2bb35 commit 44b3cc2
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Only accretive/fixative changes will be made from now on.

* 1.3.next in progress
* Address [#268](https://github.com/seancorfield/next-jdbc/issues/268) by expanding the documentation around `insert-multi!` and `insert!`.

* 1.3.909 -- 2023-12-16
* Address [#267](https://github.com/seancorfield/next-jdbc/issues/267) by adding the `:schema-opts` option to override the default conventions for identifying foreign keys in columns.
* Address [#264](https://github.com/seancorfield/next-jdbc/issues/264) by letting `insert-multi!` accept empty rows (and producing an empty result vector). This improves compatibility with `clojure.java.jdbc`.
Expand Down
23 changes: 20 additions & 3 deletions doc/friendly-sql-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,14 @@ Given a table name (as a keyword) and a hash map of column names and values, thi
{:suffix "RETURNING *"})
```

If you have multiple rows (hash maps) to insert and they all have the same
set of keys, you can use `insert-multi!` instead (see below), which will
perform a single multi-row insertion, which will generally be faster.

## `insert-multi!`

Given a table name (as a keyword), a vector of column names, and a vector of row value vectors, this performs a multi-row insertion into the database:
Given a table name (as a keyword), a vector of column names, and a vector of
row value vectors, this performs a single multi-row insertion into the database:

```clojure
(sql/insert-multi! ds :address
Expand All @@ -59,7 +64,11 @@ Given a table name (as a keyword), a vector of column names, and a vector of row
"Aunt Sally" "[email protected]"] {:return-keys true})
```

Given a table name (as a keyword) and a vector of hash maps, this performs a multi-row insertion into the database:
All the row vectors must be the same length, and must match the number of
columns specified.

Given a table name (as a keyword) and a vector of hash maps, this performs a
single multi-row insertion into the database:

```clojure
(sql/insert-multi! ds :address
Expand All @@ -73,7 +82,15 @@ Given a table name (as a keyword) and a vector of hash maps, this performs a mul
"Aunt Sally" "[email protected]"] {:return-keys true})
```

> Note: this expands to a single SQL statement with placeholders for every
All the hash maps must have the same set of keys, so that the vector of hash
maps can be converted to a vector of columns names and a vector of row value
vectors, as above, so a single multi-row insertion can be performed.

If you wish to insert multiple hash maps that do not have identical keys, you
need to iterate over `insert!` and insert one row at a time, which will
generally be much slower.

> Note: both of these expand to a single SQL statement with placeholders for every
value being inserted -- for large sets of rows, this may exceed the limits
on SQL string size and/or number of parameters for your JDBC driver or your
database. Several databases have a limit of 1,000 parameter placeholders.
Expand Down
2 changes: 1 addition & 1 deletion doc/migration-from-clojure-java-jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ If you were using other forms of the `db-spec` hash map, you'll need to adjust t
The `next.jdbc.sql` namespace contains several functions with similarities to `clojure.java.jdbc`'s core API:

* `insert!` -- similar to `clojure.java.jdbc/insert!` but only supports inserting a single map,
* `insert-multi!` -- similar to `clojure.java.jdbc/insert-multi!` but only supports inserting columns and a vector of row values,
* `insert-multi!` -- similar to `clojure.java.jdbc/insert-multi!` but only supports inserting columns and a vector of row values, or a sequence of hash maps _that all have the same keys_ -- unlike `clojure.java.jdbc/insert-multi!`, you should always get a single multi-row insertion,
* `query` -- similar to `clojure.java.jdbc/query`,
* `find-by-keys` -- similar to `clojure.java.jdbc/find-by-keys` but will also accept a partial where clause (vector) instead of a hash map of column name/value pairs,
* `get-by-id` -- similar to `clojure.java.jdbc/get-by-id`,
Expand Down
4 changes: 2 additions & 2 deletions src/next/jdbc/sql.clj
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
generated keys.
Given a connectable object, a table name, a sequence of hash maps of data,
inserts the data as multiple rows in the database and attempts to return
a vector of maps of generated keys.
which all have the same set of keys, inserts the data as multiple rows in
the database and attempts to return a vector of maps of generated keys.
If called with `:batch` true will call `execute-batch!` - see its documentation
for situations in which the generated keys may or may not be returned as well as
Expand Down

0 comments on commit 44b3cc2

Please sign in to comment.