Closed Aflynn50 closed 2 months ago
Out of curiosity more than anything. From the PR description, the SQL sent to the driver is:
INSERT INTO t (col1, col2, col3, col4) VALUES (@sqlair_0, @sqlair_1, "v3", @sqalir_2), (@sqlair_3, @sqlair_4, "v3", @sqalir_5), (@sqlair_6, @sqlair_7, "v3", @sqalir_8)
Yet, col2
, will always be a map for a constant value, so the query could be turned into?
INSERT INTO t (col1, col2, col3, col4) VALUES (@sqlair_0, @sqlair_1, "v3", @sqalir_2), (@sqlair_3, @sqlair_1, "v3", @sqalir_4), (@sqlair_5, @sqlair_1, "v3", @sqalir_6)
Out of curiosity more than anything. From the PR description, the SQL sent to the driver is:
INSERT INTO t (col1, col2, col3, col4) VALUES (@sqlair_0, @sqlair_1, "v3", @sqalir_2), (@sqlair_3, @sqlair_4, "v3", @sqalir_5), (@sqlair_6, @sqlair_7, "v3", @sqalir_8)
Yet,
col2
, will always be a map for a constant value, so the query could be turned into?INSERT INTO t (col1, col2, col3, col4) VALUES (@sqlair_0, @sqlair_1, "v3", @sqalir_2), (@sqlair_3, @sqlair_1, "v3", @sqalir_4), (@sqlair_5, @sqlair_1, "v3", @sqalir_6)
Thats a good point, no reason not to do this. I've changed the code and updated the PR description to reflect this.
I'd love to see a full end to end test added to package_test.go that baked in the bulk insert changes.
I think the more common approach that I regularly want to use bulk insert in sqlair for is the following:
type S struct { a string `db:"col1"` b string `db:"col2"` c string `db:"col3"` d string `db:"col4"` } s := sqlair.MustPrepare( "INSERT INTO t (col1, col2, col3, col4) VALUES ($S.*)", S{}, ) db.Query( s, []S{ {a: "a1", b: "b1", c: "c1", d: "d1"}, {a: "a2", b: "b2", c: "c2", d: "d2"}, }, )
Name Value sqlair_0 "a1" sqlair_1 "b1" sqlair_2 "c1" sqlair_3 "d1" sqlair_4 "a2" sqlair_5 "b2" sqlair_6 "c2" sqlair_7 "d2"
Good point, I'd been meaning to add something to package_test but had forgotten. I've added a test now that has a simple case and a more complex case of a bulk insert.
SQLair currently supports insert expressions, but not bulk inserts. To insert multiple rows into a database with SQLair, users currently have to execute the same statement multiple times using a for loop or write a query that inserts a fixed number of rows by explicitly writing out each row with separate input expressions for every column.
Additionally, users may want to bulk insert where network latency needs to be minimised such as in Juju where the distributed database requires multiple trips.
Bulk inserts are supported using the same syntax currently used for INSERTS. If one or more of the types passed to
Query
is a slice instead of a simple value, then it becomes a bulk insert with any other values in the INSERT remaining constant.For example:
The query sent to the DB from the above example will be:
Note that SQLair will check that all the slices passed to Query for bulk INSERTS are of the same cardinality, else throw out an error.