Multiple rows can be inserted in a batch by passing an array of structs to insert.
This is not the same as looping over and array and calling insert in the loop. Using an array with insert will batch the inserts in one SQL call. Looping over an array and calling insert each time will create a SQL request for each item in the array. Bottom line, pass your array to insert!
An upsert is a batch operation that either inserts or updates a row depending on if a target match is found. If a row is matched with the target column(s), then the matched row is updated. Otherwise a new row is inserted.
In most database grammars, the target columns are required to be primary key or unique indexes.
MERGE [stats] AS [qb_target]
USING (VALUES (?, ?, ?), (?, ?, ?)) AS [qb_src]
([postId], [viewedDate], [views])
ON [qb_target].[postId] = [qb_src].[postId]
AND [qb_target].[viewedDate] = [qb_src].[viewedDate]
WHEN MATCHED THEN UPDATE
SET [views] = stats.views + 1
WHEN NOT MATCHED BY TARGET THEN INSERT
([postId], [viewedDate], [views])
VALUES
([postId], [viewedDate], [views])
INSERT INTO "stats"
("postId", "viewedDate", "views")
VALUES
(?, ?, ?),
(?, ?, ?)
ON CONFLICT ("postId", "viewedDate") DO UPDATE
"views" = stats.views + 1
MERGE INTO "STATS" "QB_TARGET"
USING (
SELECT ?, ?, ? FROM dual
UNION ALL
SELECT ?, ?, ? FROM dual
) "QB_SRC"
ON "QB_TARGET"."POSTID" = "QB_SRC"."POSTID"
AND "QB_TARGET"."VIEWEDDATE" = "QB_SRC"."VIEWEDDATE"
WHEN MATCHED THEN UPDATE
SET "VIEWS" = stats.views + 1
WHEN NOT MATCHED THEN INSERT
("POSTID", "VIEWEDDATE", "VIEWS")
VALUES
("QB_SRC"."POSTID", "QB_SRC"."VIEWEDDATE", "QB_SRC"."VIEWS")
A source callback or QueryBuilder instance can be used instead of explicit values. This allows you to do upserts across tables or subqueries.
To do this, provide a source that is either a function to configure a new QueryBuilder instance or an already configured QueryBuilder instance. Then specify the columns that will be affected as an array of strings to values.
INSERT INTO `users`
(`username`, `active`, `createdDate`, `modifiedDate`)
SELECT `username`, `active`, `createdDate`, `modifiedDate`
FROM `activeDirectoryUsers`
ON DUPLICATE KEY UPDATE
`active` = VALUES(`active`),
`modifiedDate` = VALUES(`modifiedDate`)
MERGE [users] AS [qb_target]
USING (
SELECT [username], [active], [createdDate], [modifiedDate]
FROM [activeDirectoryUsers]
) AS [qb_src]
ON [qb_target].[username] = [qb_src].[username]
WHEN MATCHED THEN UPDATE
SET [active] = [qb_src].[active],
[modifiedDate] = [qb_src].[modifiedDate]
WHEN NOT MATCHED BY TARGET THEN INSERT
([username], [active], [createdDate], [modifiedDate])
VALUES ([username], [active], [createdDate], [modifiedDate]);
INSERT INTO "users"
("username", "active", "createdDate", "modifiedDate")
SELECT "username", "active", "createdDate", "modifiedDate"
FROM "activeDirectoryUsers"
ON CONFLICT ("username") DO UPDATE
"active" = EXCLUDED."active",
"modifiedDate" = EXCLUDED."modifiedDate"
MERGE INTO "USERS" "QB_TARGET"
USING (
SELECT "USERNAME", "ACTIVE", "CREATEDADATE", "MODIFIEDDATE"
FROM "ACTIVEDIRECTORYUSERS"
) "QB_SRC"
ON "QB_TARGET"."USERNAME" = "QB_SRC"."USERNAME"
WHEN MATCHED THEN UPDATE
SET "ACTIVE" = "QB_SRC"."ACTIVE",
"MODIFIEDDATE" = "QB_SRC"."MODIFIEDDATE"
WHEN NOT MATCHED THEN INSERT
("USERNAME", "ACTIVE", "CREATEDDATE", "MODIFIEDDATE")
VALUES
(
"QB_SRC"."USERNAME",
"QB_SRC"."ACTIVE",
"QB_SRC"."CREATEDDATE",
"QB_SRC"."MODIFIEDDATE"
)
The id argument is a convenience to delete a single record by id.
QueryBuilder
query.from( "users" )
.delete( 1 );
MySQL
DELETE FROM `users`
WHERE `id` = ?
returning
returning is only supported in PostgresGrammar,SqlServerGrammar, and SQLiteGrammar. Using this method on unsupported grammars will result in an UnsupportedOperation exception. Be aware that using this method constrains your grammar choices.
Specifies columns to be returned from the insert query.
DELETE FROM [users]
OUTPUT DELETED.[id]
WHERE [active] = ?
DELETE FROM "users" WHERE "active" = ?
RETURNING "id"
DELETE FROM "users" WHERE "active" = ?
RETURNING "id"
You can also use raw Expressions in a returning call. This is especially useful for SQL Server returning both the old and new values from an update call.