Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I UPDATE a row in a table or INSERT it if it doesn't exist?

I have the following table of counters:

CREATE TABLE cache (     key text PRIMARY KEY,     generation int ); 

I would like to increment one of the counters, or set it to zero if the corresponding row doesn't exist yet. Is there a way to do this without concurrency issues in standard SQL? The operation is sometimes part of a transaction, sometimes separate.

The SQL must run unmodified on SQLite, PostgreSQL and MySQL, if possible.

A search yielded several ideas which either suffer from concurrency issues, or are specific to a database:

  • Try to INSERT a new row, and UPDATE if there was an error. Unfortunately, the error on INSERT aborts the current transaction.

  • UPDATE the row, and if no rows were modified, INSERT a new row.

  • MySQL has an ON DUPLICATE KEY UPDATE clause.

EDIT: Thanks for all the great replies. It looks like Paul is right, and there's not a single, portable way of doing this. That's quite surprising to me, as it sounds like a very basic operation.

like image 756
Remy Blank Avatar asked Mar 27 '09 17:03

Remy Blank


People also ask

How do you insert if row does not exist?

There are three ways you can perform an “insert if not exists” query in MySQL: Using the INSERT IGNORE statement. Using the ON DUPLICATE KEY UPDATE clause. Or using the REPLACE statement.

Which command insert rows that do not exist and update the rows that exist?

Using INSERT ... ON DUPLICATE KEY UPDATE statement will update the values of the row.


2 Answers

MySQL (and subsequently SQLite) also support the REPLACE INTO syntax:

REPLACE INTO my_table (pk_id, col1) VALUES (5, '123'); 

This automatically identifies the primary key and finds a matching row to update, inserting a new one if none is found.

Documentation: https://dev.mysql.com/doc/refman/8.0/en/replace.html

like image 61
andygeers Avatar answered Oct 07 '22 23:10

andygeers


SQLite supports replacing a row if it already exists:

INSERT OR REPLACE INTO [...blah...] 

You can shorten this to

REPLACE INTO [...blah...] 

This shortcut was added to be compatible with the MySQL REPLACE INTO expression.

like image 40
Kyle Cronin Avatar answered Oct 08 '22 00:10

Kyle Cronin