我需要更新数据库中的记录,但我不知道该记录是否已存在。如果存在,请更新它,否则插入它。现在我想出了这段代码:
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
。如果没有更改,则affected_rows为0
,即使该记录已存在。但这会触发INSERT语句。这个失败是因为user_id字段是唯一的,现在我忽略了这一点,所以我的代码工作正常。
但这是要走的路吗? 或者我应该先做一个选择而不是更新或插入?
答案 0 :(得分:4)
您可以使用INSERT INTO user_meta SET user_id = 125, active = 0
ON DUPLICATE KEY UPDATE active = 0
使用此方法在事务上是安全的,因为MySQL在一个隐式事务中处理它。您当前的方法允许分割时刻,其中两个并发请求可能会相互干扰。
假设您使用的是MySQL 5.7:https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
您的查询将如下所示:
INSERT ... ON DUPLICATE KEY
<强>更新强> 只是详细说明当前方法在事务上不安全的原因,想象两个并发请求并行执行。
您是显式启动并完成事务,还是隐式做(例如通过Client
)MySQL将负责确保上述内容通过阻止第二个请求直到第一个请求结束,不会发生错误的情况。
答案 1 :(得分:4)
MySQL有一个内置的解决方案 - on duplicate key update
子句:
INSERT INTO user_meta (user_id, active)
VALUES (125, 0)
ON DUPLICATE KEY UPDATE active = 0
答案 2 :(得分:1)
使用mysql ON DUPLICATE KEY UPDATE
来检查db中是否已存在记录。您的表必须具有unique
类型的列。您的user_id
列是唯一类型。查看文档here
INSERT INTO user_meta (user_id, active)
VALUES (125, 0)
ON DUPLICATE KEY UPDATE active = 0