sql >> データベース >  >> RDS >> Mysql

PostgreSQLのmerge_db(別名upsert)関数をMySQLに変換する方法

    MySQL5.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');
    

    いくつかの考え:

    • 最初に更新を行ってから、 @ROW_COUNT() 実際に変更された行数を返すためです。更新しようとしている値が行にすでに含まれている場合、これは0になる可能性があります。
    • また、@ROW_COUNT() 複製は安全ではありません。
    • REPLACE...INTOを使用できます 。
    • InnoDBまたはトランザクションをサポートするテーブルを使用している場合は、SELECT...FOR UPDATEを使用できる場合があります。 (テストされていません)。

    INSERT...ON DUPLICATE KEY UPDATEを使用するだけで、このソリューションにメリットはありません。 。




    1. JPAを介して行をランダムに選択

    2. ユーザー'ユーザー'@'%'と'ユーザー'@'localhost'は同じではありませんか?

    3. すべてのPOSTデータを取得し、メールで送信します

    4. ユーザーのMYSQLSELECTランク(xより大きくyより小さい)