sql >> Database >  >> RDS >> Mysql

Hoe de functie PostgreSQL merge_db (ook bekend als upsert) in MySQL te vertalen?

Getest op 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 is a unique key constraint error then 
            -- someone made a concurrent insert. Reset the sentinel
            -- and try again.
            DECLARE ER_DUP_UNIQUE CONDITION FOR 23000;
            DECLARE CONTINUE HANDLER FOR ER_DUP_UNIQUE BEGIN
                SET done = FALSE;
            END;

            SET done = TRUE;
            SELECT COUNT(*) INTO @count FROM db WHERE a = k;
            -- Race condition here. If a concurrent INSERT is made after
            -- the SELECT but before the INSERT below we'll get a duplicate
            -- key error. But the handler above will take care of that.
            IF @count > 0 THEN 
                UPDATE db SET b = data WHERE a = k;
            ELSE 
                INSERT INTO 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');

Enkele gedachten:

  • Je kunt niet eerst een update doen en dan @ROW_COUNT() omdat het het aantal daadwerkelijk gewijzigde rijen retourneert. Dit kan 0 zijn als de rij al de waarde heeft die u probeert bij te werken.
  • Ook @ROW_COUNT() is niet veilig voor replicatie.
  • Je zou REPLACE...INTO . kunnen gebruiken .
  • Als u InnoDB of een tabel met transactie-ondersteuning gebruikt, kunt u mogelijk SELECT...FOR UPDATE gebruiken (niet getest).

Ik zie geen voordeel in deze oplossing boven het gebruik van INSERT...ON DUPLICATE KEY UPDATE .




  1. Fout #2002 Kan geen verbinding maken met lokale MySQL-server via socket '/Applications/MAMP/tmp/mysql/mysql.sock' (2)

  2. Invoegen in MySQL vanuit PHP (jQuery/AJAX)

  3. Hoe de korte dagnaam van een datum in MariaDB te krijgen?

  4. Hoe MySQL op Debian 7 te installeren