REPLACE的運行與INSERT很相似。只有一點例外,假如表中的一箇舊記錄與一個用於PRIMARY KEY或一個UNIQUE索引的新記錄具有相同的值,則在新記錄被插入之前,舊記錄被刪除。
需要注意的是,除非表有一個PRIMARY KEY或UNIQUE索引,否則,使用一個REPLACE語句沒有意義,無法確定是否要刪除舊數據。
所有列的值均取自在REPLACE語句中被指定的值。所有缺失的列被設置爲各自的默認值,這和INSERT一樣。您不能從當前行中引用值,也不能在新行中使用值。
REPLACE語句會返回一個數,來指示受影響的行的數目。該數是被刪除和被插入的行數的和。如果對於一個單行REPLACE該數爲1,則一行被插入,同時沒有行被刪除。如果該數大於1,則在新行被插入前,有一個或多箇舊行被刪除。
操作過程:
- 嘗試把新行插入到表中
- 當因爲對於主鍵或唯一關鍵字出現重複關鍵字錯誤而造成插入失敗時:
- 從表中刪除含有重複關鍵字值的衝突行
- 再次嘗試把新行插入到表中
-
特別注意:
在使用replace語句時,如果沒有覆蓋到所有字段,那麼沒有被覆蓋的字段的值就會丟失。例如:
CREATE TABLE `hotmblog_login` (
`uid` bigint(20) UNSIGNED NOT NULL,
`status` tinyint(3) UNSIGNED NOT NULL,
`state` bigint(20) UNSIGNED NOT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
`uid` bigint(20) UNSIGNED NOT NULL,
`status` tinyint(3) UNSIGNED NOT NULL,
`state` bigint(20) UNSIGNED NOT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
在查詢uid=2057464133時,replace只修改了uid和status字段,那麼state字段的值就被默認值覆蓋掉了。
mysql> select * from hotmblog_login where uid = 2057464133;
+------------+--------+-------+
| uid | status | state |
+------------+--------+-------+
| 2057464133 | 0 | 2 |
+------------+--------+-------+
1 row in set (0.00 sec)
mysql> replace into hotmblog_login (`uid`, `status`) VALUES (2057464133, 0);
Query OK, 2 rows affected, 1 warning (0.01 sec)
mysql> select * from hotmblog_login where uid = 2057464133;
+------------+--------+-------+
| uid | status | state |
+------------+--------+-------+
| 2057464133 | 0 | 0 |
+------------+--------+-------+
1 row in set (0.00 sec)