Open isolaol opened 10 years ago
Thanks for your input, I'll take it into account
MySQL 5 also supports an "upsert" syntax as documented here:
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
This blog post provides a great example of using it:
http://mechanics.flite.com/blog/2013/09/30/how-to-do-an-upsert-in-mysql/
mysql> select * from sakila.actor where actor_id = 50;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+-----------+---------------------+
| 50 | NATALIE | HOPKINS | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.01 sec)
mysql> insert into sakila.actor (actor_id, first_name, last_name, last_update)
-> values (50,'NATALIE','SMITH','2013-09-27 12:34:56')
-> on duplicate key update
-> first_name = values(first_name),
-> last_name = values(last_name),
-> last_update = values(last_update);
Query OK, 2 rows affected (0.00 sec)
mysql> select * from sakila.actor where actor_id = 50;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+-----------+---------------------+
| 50 | NATALIE | SMITH | 2013-09-27 12:34:56 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)
Some key takeaways from the docs:
With on duplicate key update, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values.
If a table contains an AUTO_INCREMENT column and INSERT ... UPDATE inserts a row, the LAST_INSERT_ID() function returns the AUTO_INCREMENT value. If the statement updates a row instead [a.k.a. the number of affected-rows is 2], LAST_INSERT_ID() is not meaningful.
Cool, thank you!
Be careful with MERGE on MS SQL without transaction. https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
Dear developer,
The current incarnation (2.3) of SqlFu has Upsert method in CrudHelpers.cs. The upsert (ie. UpdateOrInsert) is a great facility and used in real world applications. I like it!
The implementation seems to try to update the record first and then insert it if the update fails. This two-pass protocol is "chatty". The single statement upsert would be far more efficient due to reduced round-trips to the database.
There are two ways of implementing single statement upsert. The traditional method is a combination of both UPDATE and INSERT statements. The fast method takes advantage of MERGE statement and VALUES table constructor.
A demostration of upsert without autogenerated primary key.
A demostration of upsert when primary key value is generated by database. Please note the presence of OUTPUT clause. It allows the library the read back any value generated by the database.
I prefer MERGE statement over combining IF EXISTS, UPDATE and INSERT. MERGE statement is easier to query optimizer and does its job in single pass. The added benefit of MERGE statement is atomicity. I do not need to wrap the call of upsert method inside transaction!
For more information about the implementation of the MERGE statement in Microsoft SQL Server, please visit http://msdn.microsoft.com/en-us/library/bb510625(v=sql.100).aspx.
MERGE statatement has been supported since SQL Server 2008.
I hope this helps you to develop the best micro-orm available to the community of the .NET developers!
Keep going!
Kind regards, Olli-Pekka Isola