今天有人问用过mysql INSERT INTO .. ON DUPLICATE KEY吗?
自己还真没有用过这个东东,在网络上搜索了下这个东东是什么...
我们先来看条SQL语句:
INSERT INTO TableName(a,b,c)
VALUES(1,2,3)
ON DUPLICATE KEY
UPDATE c=c+1;
下面来解释下这条代码是什么意思:
假设上面语句中字段a的属性为唯一unique
当在 insert 语句末尾指定了 on duplicate key update 语句时,如果新插入的新数据中 a列 的值已经在数据库中存在,则会执行后面的 update 语句,这时相当于执行了下面语句:
UPDATE TableName SET c=c+1 WHERE a=1;
反之,则执行正常的 insert 语句。
这里需要注意的是:如果行作为新记录被插入,则受影响行的值为1;如果原有的记录被更新,则受影响行的值为2。
参考资料:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
下面来看一下同时插入多行记录的情况:
字段a被定义为UNIQUE,并且原数据库表table中已存在记录(2,2,9)和(3,2,1),如果插入记录的a值与原有记录重复,则更新原有记录,否则插入新行:
INSERT INTO TABLE (a,b,c) VALUES
(1,2,3),
(2,5,7),
(3,3,6),
(4,8,2)
ON DUPLICATE KEY UPDATE b=VALUES(b);
以上SQL语句的执行,发现(2,5,7)中的a与原有记录(2,2,9)发生唯一值冲突,则执行ON DUPLICATE KEY UPDATE,将原有记录(2,2,9)更新成(2,5,9),将(3,2,1)更新成(3,3,1),插入新记录(1,2,3)和(4,8,2)
注意:ON DUPLICATE KEY UPDATE只是MySQL的特有语法,并不是SQL标准语法!
于CI中封装的方法:
/**
* The "set" function.
*
* Allows key/value pairs to be set for inserting or updating
*
* @param mixed
* @param string
* @param bool
* @return CI_DB_query_builder
*/
public function duplicate($key, $value = '', $escape = NULL)
{
$key = $this->_object_to_array($key);
if (!is_array($key)) {
$key = array($key => $value);
}
is_bool($escape) OR $escape = $this->_protect_identifiers;
foreach ($key as $k => $v) {
$this->qb_duplicate[$this->protect_identifiers($k, FALSE, $escape)] = ($escape)
? $this->escape($v) : $v;
}
return $this;
}