sql - How to translate PostgreSQL "merge_db" (aka upsert) function into MySQL -
straight manual, here's canonical example of merge_db in postgresql:
create table db (a int primary key, b text); create function merge_db(key int, data text) returns void $$ begin loop -- first try update key update db set b = data = key; if found return; end if; -- not there, try insert key -- if else inserts same key concurrently, -- unique-key failure begin insert db(a,b) values (key, data); return; exception when unique_violation -- nothing, , loop try update again. end; end loop; end; $$ language plpgsql; select merge_db(1, 'david'); select merge_db(1, 'dennis');
can expressed user-defined function in mysql, , if so, how? there advantage on mysql's standard insert...on duplicate key update
?
note: i'm looking user-defined function, not insert...on duplicate key update
.
tested on mysql 5.5.14.
create table db (a int primary key, b text); delimiter // create procedure merge_db(k int, data text) begin declare done boolean; repeat begin -- if there unique key constraint error -- made concurrent insert. reset sentinel -- , try again. declare er_dup_unique condition 23000; declare continue handler er_dup_unique begin set done = false; end; set done = true; select count(*) @count db = k; -- race condition here. if concurrent insert made after -- select before insert below we'll duplicate -- key error. handler above take care of that. if @count > 0 update db set b = data = k; else insert db (a, b) values (k, data); end if; end; until done end repeat; end// delimiter ; call merge_db(1, 'david'); call merge_db(1, 'dennis');
some thoughts:
- you can't update first , check
@row_count()
because returns number of rows changed. 0 if row has value trying update. - also,
@row_count()
not replication safe. - you use
replace...into
. - if using innodb or table transaction support might able use
select...for update
(untested).
i see no advantage solution on using insert...on duplicate key update
.
Comments
Post a Comment