This is probably not properly supported:
INSERT INTO beautiful (name, age)
VALUES
('Helen', 24),
('Katrina', 21),
('Samia', 22),
('Hui Ling', 25),
('Yumie', 29)
ON DUPLICATE KEY UPDATE
age = VALUES(age),
...
As referenced here:
Not sure if this is the same issue, but I'd love to be able to have something like context.batchInsert().onDuplicateKeyUpdate(true).
@adriancole : Could you please create a separate issue for this?
Sure!
If you use the following on a normal insert query builder
.onDuplicateKeyUpdate()
.set(field("DateValue"), (Object)field("VALUES(DateValue)"))
.set(field("NumericValue"), (Object)field("VALUES(NumericValue)"))
.set(field("TextValue"), (Object)field("VALUES(TextValue)"));
Then a call to getSQL() gives you the following SQL:
on duplicate key update
DateValue = VALUES(DateValue),
NumericValue = VALUES(NumericValue),
TextValue = VALUES(TextValue)
There might be a better way to do this, but this worked for me.
@killermonk : Thanks for contributing. This is actually a very good way to go ahead and do this. Alternatively, you could extract the functionality in your own class:
class MyDSL {
public static <T> Field<T> values(Field<T> field) {
return DSL.field("VALUES({0})", field.getDataType(), field);
}
}
That could now be used as such in a type safe way:
.onDuplicateKeyUpdate()
.set(T.DATE_VALUE, MyDSL.values(T.DATE_VALUE))
.set(T.NUMERIC_VALUE, MyDSL.values(T.NUMERIC_VALUE))
.set(T.TEXT_VALUE, MyDSL.values(T.TEXT_VALUE))
Added MySQLDSL.values() due to popular request.
@adriancole Could you share the url of the separate issue about text.batchInsert().onDuplicateKeyUpdate(true) ? I want to use this functionality as well.
@demongaorui as far as I can tell I never created that issue
@adriancole I see...
@lukaseder Do we have a way to do ext.batchInsert().onDuplicateKeyUpdate(true) now?
I want to do multiple rows insert/onDuplicateKeyUpdate in only one execution.
@demongaorui: The suggested API probably won't work this way. Perhaps, we'll add a UpdatableRecord.upsert() and thus a batchUpsert() method at some point, but the ON DUPLICATE KEY UPDATE clause is too powerful to be passed to the batchInsert() statement as a simple extension.
Right now, however, you can easily batch actual ON DUPLICATE KEY UPDATE statements like this:
insertInto(TABLE).set(record).onDuplicateKeyUpdate().set(record)
Hope this helps
@lukaseder Thank you very much for rapid reply.
Currently, I am using
for (Record record : records) {
db.insertInto(TABLE).set(record)
.onDuplicateKeyUpdate().set(record)
.execute();
}
But this will cause running many queries to db. For direct insert, we could do like
db.insertInto(TABLE).set(record1).newRecord().set(record2).execute();
So all the records could be inserted in just one execution.
Is there any way we could do insert/onDuplicateKeyUpdate for multiple records in one execution?
Yes, I'm sorry I may not have been clear. You can batch the statements with this API:
https://www.jooq.org/doc/latest/manual/sql-execution/batch-execution
@lukaseder Thank you very much for your info!
Most helpful comment
@killermonk : Thanks for contributing. This is actually a very good way to go ahead and do this. Alternatively, you could extract the functionality in your own class:
That could now be used as such in a type safe way: