2017-07-19 83 views
-2

我需要更新數據庫中的記錄,但我不知道該記錄是否已經存在。如果存在,請更新它,否則插入它。現在,我想出了這個代碼:MYSQL更新或用PHP插入

1: <?php 
2: $query = "UPDATE user_meta SET active = '0' WHERE user_id = '125'"; 
3: $mysqli->query($query); 
4: 
5: if($mysqli->affected_rows == 0){ 
6:  $query = "INSERT INTO user_meta (user_id, active) VALUES ('125', 0)"; 
7:  $mysqli->query($query); 
8: } 

表:

CREATE TABLE `user_meta` (
    `user_id` int(11) DEFAULT NULL, 
    `active` tinyint(4) DEFAULT NULL, 
    UNIQUE KEY `user_id` (`user_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

此代碼工作爲我好,但它實際上生成我忽視的錯誤。

問題出在這一行5。如果沒有更改,受影響的行是0,即使記錄已經存在。但是這會觸發INSERT語句。這一個失敗,因爲user_id字段是唯一的,現在我忽略這個,所以我的代碼工作正常。

但這是要走的路嗎? 或者我應該先做一個選擇,然後更新或插入?

+0

使USER_ID int和不串並檢查 – Exprator

+0

執行插入或更新之前,簡單地火一把'SELECT查詢來獲取計算該用戶id'。如果計數是1,則執行更新,否則執行插入。 –

回答

4

可以使用INSERT ... ON DUPLICATE KEY

使用這種方法會事務安全,因爲MySQL是處理它在一個隱式事務解決這個問題。您當前的方法允許在兩個併發請求可能相互干擾的情況下進行分割。

假設你在MySQL 5.7:https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

您的查詢應該是這樣的:

INSERT INTO user_meta SET user_id = 125, active = 0 
    ON DUPLICATE KEY UPDATE active = 0 

更新: 只是爲了解釋爲何當前的方法是事務性不安全,想象兩個併發請求並行執行。

  1. 請求1嘗試更新,看到0受影響的行。
  2. 請求2嘗試更新,看到0受影響的行。
  3. 請求1插入新記錄。
  4. 請求2插入新記錄。

無論您明確開始和完成交易,或者是否隱含做(例如,通過INSERT ... ON DUPLICATE KEY)MySQL將負責確保上述故障的情況下不通過阻斷第二個請求發生的責任直到第一次結束。

4

MySQL有此內置的解決方案 - on duplicate key update條款:

INSERT INTO user_meta (user_id, active) 
VALUES (125, 0) 
ON DUPLICATE KEY UPDATE active = 0 
1

用mysql ON DUPLICATE KEY UPDATE檢查已經存在於數據庫或不予備案。你的餐桌必須有一個有unique類型的列。這裏您的user_id列是唯一類型。檢查機制的文檔here

INSERT INTO user_meta (user_id, active) 
VALUES (125, 0) 
ON DUPLICATE KEY UPDATE active = 0