0

What is the best method to atomically update a row if exists, else insert a new row into an table?

e.g. say we have this example below.

CREATE TABLE Test(
id integer,
val varchar(255)
)

DELIMITER $$

DROP PROCEDURE IF EXISTS `TestUpsert` $$
CREATE PROCEDURE `TestUpsert` (in value1 varchar(255), in id1 int)
BEGIN
    IF EXISTS(Select 1 from Test where id=id1) THEN
        UPDATE Test set val  = value1 where id = id1;
    ELSE
        insert into Test(id, val) VALUES (id1, value1);
    END IF;

END $$

DELIMITER ;

What changes can we make to TestUpsert to make it atomic?

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
Max
  • 113
  • 1
  • 1
  • 6

2 Answers2

1

Use on duplicate key update:

CREATE PROCEDURE `TestUpsert` (
    in in_value varchar(255),
    in in_id int
)
BEGIN
    insert into test(id, val)
        values (in_id, in_val)
        on duplicate key update val = in_val;
END $$

I should add that for this to work, test.id has to be declared as the primary key or unique.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
0

I recommend you read about INSERT ... ON DUPLICATE KEY UPDATE.

See my lengthy answer about this statement here: https://stackoverflow.com/a/548570/20860

Community
  • 1
  • 1
Bill Karwin
  • 538,548
  • 86
  • 673
  • 828