Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak przetłumaczyć funkcję PostgreSQL merge_db (aka upsert) na MySQL?

Testowane na 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');

Kilka myśli:

  • Nie możesz najpierw zaktualizować, a potem sprawdzić @ROW_COUNT() ponieważ zwraca liczbę faktycznie zmienionych wierszy. Może to być 0, jeśli wiersz ma już wartość, którą próbujesz zaktualizować.
  • Również @ROW_COUNT() nie jest bezpieczna dla replikacji.
  • Możesz użyć REPLACE...INTO .
  • Jeśli używasz InnoDB lub tabeli z obsługą transakcji, możesz użyć SELECT...FOR UPDATE (nietestowane).

Nie widzę żadnej przewagi tego rozwiązania nad zwykłym użyciem INSERT...ON DUPLICATE KEY UPDATE .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak utworzyć przechowywaną funkcję agregującą MySQL?

  2. Jak przechowywać historię aktualizacji rekordów w MySQL?

  3. Tworzenie systemu kodów rabatowych (MySQL/php)

  4. Jaki jest największy numer ID, który autoincrement może wygenerować w mysql

  5. MySQL JEŻELI NIE NULL, to wyświetl 1, w przeciwnym razie wyświetl 0