Mysql 插入。。。在哪里进行重复密钥更新?
我正在做一个Mysql 插入。。。在哪里进行重复密钥更新?,mysql,replication,Mysql,Replication,我正在做一个插入。。。在重复密钥更新时但我需要更新部分是有条件的,只有在某些额外条件发生更改时才执行更新 但是,其中在此更新中是不允许的。有什么解决办法吗 我无法组合使用INSERT/UPDATE/SELECT,因为这需要在复制过程中工作。您可以使用两个INSERT语句。。因为您可以将where子句添加到源数据的select部分 选择两组数据,一组是使用“复制时”插入的,另一组是不使用“复制时”插入的。这是我们的最终解决方案,非常有效 插入忽略将确保主设备和从设备上都存在该行,以防它们发生转移
插入。。。在重复密钥更新时
但我需要更新部分是有条件的,只有在某些额外条件发生更改时才执行更新
但是,其中
在此更新中是不允许的。有什么解决办法吗
我无法组合使用INSERT/UPDATE/SELECT,因为这需要在复制过程中工作。您可以使用两个INSERT语句。。因为您可以将where子句添加到源数据的select部分
选择两组数据,一组是使用“复制时”插入的,另一组是不使用“复制时”插入的。这是我们的最终解决方案,非常有效
插入忽略将确保主设备和从设备上都存在该行,以防它们发生转移
更新。。。其中确保在完成所有复制后,只有最新的全局更新才是最终结果
mysql> desc test;
+-------+--------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+-------------------+-------+
| id | int(11) | NO | PRI | NULL | |
| value | varchar(255) | YES | | NULL | |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | |
+-------+--------------+------+-----+-------------------+-------+
mysql> insert ignore into test values (4, "foo", now());
mysql> update test set value = "foo", ts = now() where id = 4 and ts <= now();
mysql>desc测试;
+-------+--------------+------+-----+-------------------+-------+
|字段|类型|空|键|默认|额外|
+-------+--------------+------+-----+-------------------+-------+
|id | int(11)| NO | PRI | NULL |
|值| varchar(255)|是| |空| |
|ts |时间戳|否| |当前| U时间戳|
+-------+--------------+------+-----+-------------------+-------+
mysql>在测试值中插入ignore(4,“foo”,now());
mysql>更新测试集value=“foo”,ts=now(),其中id=4和ts我建议您使用IF()来实现这一点
参考:
插入每日事件(创建时间、上次事件id、上次事件创建时间)
数值('2010-01-19',23',2010-01-19 10:23:11')
关于重复密钥更新
last_event_id=IF(last_event_created_at<值(last_event_created_at))、值(last_event_id)、last_event_id);
表php\u lock
:
name
:idString,locked
:bool,
时间
:时间戳,被
锁定:字符串
要插入的值或
更新
1,当前时间戳,'script'
其中name
='wwww'和
锁定
=2
重复键上的不允许使用where子句,因此有两种方法可以实现相同的效果
如果你知道大部分时间你会得到重复的钥匙然后
a。首先使用Update query和where子句更新表
B如果更新失败,则使用插入查询将记录插入表中
如果您大部分时间都知道要插入到表中,那么
a。使用Insert ignore查询将记录插入到表中-如果发现重复的键,它实际上会忽略插入
B如果插入忽略失败,则使用更新查询更新记录
有关的参考,请插入ignore
概述
- 第二名用户希望将之前的更改为之后的
问题
- 如果MySQL检测到重复的主键,AWUpsertCondy不希望插入查询失败
- MySQL不支持重复密钥更新时带有
的条件WHERE子句
解决方案
- MySQL支持带有
IF()
函数的条件子句
- 这里我们有一个简单的条件,只更新userid小于9的项目
插入zzdemo_表02
(lname,userid)
挑选
用户名
从(
挑选
用户名
从…起
ZZU表01
)as tt01
关于重复密钥更新
userid=IF(@doupdate:=IF((tt01.userid<9),True,False),
tt01.userid,zzdemo_table02.userid)
,lname=IF(@doupdate,tt01.lname,zzdemo_table02.lname)
;
陷阱
- 我们引入一个MySQL变量
@doupdate
,以标记更新行是否满足条件。然后,我们对UPDATE语句中使用的所有数据库列使用相同的变量
- 在第一个条件中,我们都声明变量并确定条件是否适用。这种方法可能比WHERE条款更麻烦
另见
我从来不知道我可以访问更新部分中的原始表值。这可能解决了我的问题(虽然我以前的解决方法很好:))MySQL可能会抱怨“字段列表中的列不明确”-然后您需要在重复键上使用:更新daily_events.last_event_id=IF(daily_events.last_event_created_at
发布到webfellas.com的链接已经死了,很遗憾。发布到webfellas.com的链接现在可以使用了插入忽略
怎么会失败?如果尝试插入相同的唯一键插入忽略
将失败。不,这就是忽略
的作用。它忽略了重复键异常。解释在@lexu答案中:两条语句,第一条是insert ignore
,第二条类似于update ignore
。看起来第二条语句只是在执行update test set value=“foo”,ts=now(),其中id=4和ts
除了非常复杂的方式。是的,你是对的。自从发布此答案后,我将代码更改为insert ignore…
,然后是更新。。。。您是否可以相应地更新您的答案,以便其他人也可以从您的结论中受益?
INSERT INTO daily_events (created_on, last_event_id, last_event_created_at)
VALUES ('2010-01-19', 23, '2010-01-19 10:23:11')
ON DUPLICATE KEY UPDATE
last_event_id = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_id), last_event_id);
INSERT INTO `php_lock` (`name`, locked, `time`, `locked_by`)
(SELECT * FROM
(SELECT `name`,1,CURRENT_TIMESTAMP, 'script' FROM `php_lock`
WHERE `name`='wwww' AND `locked`=2
UNION (
SELECT 'wwww',1 ,CURRENT_TIMESTAMP, 'script')
) AS temp LIMIT 1)
ON DUPLICATE KEY UPDATE locked=VALUES(locked), `time`=VALUES(`time`), `locked_by`=VALUES(`locked_by`);
INSERT INTO zzdemo_table02
(lname,userid)
SELECT
lname,userid
FROM(
SELECT
lname,userid
FROM
zzdemo_table01
) as tt01
ON DUPLICATE KEY UPDATE
userid=IF(@doupdate:=IF( (tt01.userid < 9) , True, False),
tt01.userid, zzdemo_table02.userid)
,lname=IF(@doupdate, tt01.lname , zzdemo_table02.lname )
;