mysql UPDATE语句逐个更新列?
我在mysql 8中编写了一个查询,在插入的重复键上,因为有一个唯一的索引,所以它只在特定条件下更新受影响的行。我的条件是列上的mysql UPDATE语句逐个更新列?,mysql,sql,sql-update,mysql-8.0,Mysql,Sql,Sql Update,Mysql 8.0,我在mysql 8中编写了一个查询,在插入的重复键上,因为有一个唯一的索引,所以它只在特定条件下更新受影响的行。我的条件是列上的start\u值是否已更改。所以我写了这个查询 INSERT INTO timers ( started_on, end_on, message, first_alert_before_end_time, alerts_interval,
start\u值是否已更改。所以我写了这个查询
INSERT INTO timers (
started_on,
end_on,
message,
first_alert_before_end_time,
alerts_interval,
referred_flow_instance_id,
referred_page_id,
referred_json_timer_id,
started_by_user_id
) VALUES (
'2025-01-06',
DATE_ADD('2025-01-06', INTERVAL 5184000 SECOND),
'Sta scadendo il fascicolo',
2592000,
86400,
1413,
14,
1,
79
)
ON DUPLICATE KEY
UPDATE
started_on = IF( DATE(started_on) = DATE('2025-01-01'), started_on, '2025-01-06'),
end_on = IF( DATE(started_on) = DATE('2025-01-01'), end_on, DATE_ADD('2025-01-06', INTERVAL 5184000 SECOND)),
started_by_user_id = IF( DATE(started_on) = DATE('2025-01-01'), started_by_user_id, 79),
deleted_by_user_id = IF( DATE(started_on) = DATE('2025-01-01'), deleted_by_user_id, NULL),
reminded_later_by_user_id = IF( DATE(started_on) = DATE('2025-01-01'), reminded_later_by_user_id, NULL),
deleted = IF( DATE(started_on) = DATE('2025-01-01'), deleted, 0)
;
我不分析有效的插入,只分析重复关键部件的更新。
我注意到一个意外的结果:当更新中的IF条件为true时,只更新了started_on,而没有更新具有相同条件的其他列
因此,我的直觉是,我的更新查询的第一行(started\u on=IF(DATE(started\u on)=DATE('2025-01-01')、started\u on,'2025-01-06'
)突然更新了started\u on列,因此由于值发生了更改,以下条件会导致false。
我试着把更新开始的部分放在更新中所有列的末尾,现在它们都被更新了
我想确定并确认我的直觉是否正确,但在网上搜索了一下后,我什么也没找到
编辑:似乎运行通过mysql workbench从顶部开始更新的查询即使在顶部也可以运行,但我需要使用xdevapi库在节点中运行它,并且只有在放在底部时才可以运行。您的直觉是正确的。
中记录了此行为,并举例说明:
下面语句中的第二个赋值将col2设置为
当前(已更新)col1值,不是原始的col1值。结果
col1和col2具有相同的值。此行为与
标准SQL
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
单表更新分配通常从左到右进行评估
右侧
在mysql 5.6和所有版本的MariaDB中,对列的任何引用都将获得该列的原始值
对于mysql 5.7和mysql 8.0,更为复杂:
在单个表更新中,更新实际上是从左到右进行的,每个列更新都会获得列的值,就好像前面的所有更新都已应用一样
在多表更新中,对主表的任何更新似乎都是从左到右首先发生的,就像在单个表更新中一样。但是对联接表中的列的更新似乎总是在主表更新完成时获得任何值,因此对主表列的任何更改都将生效,即使这些主表列仅在语句的后面设置,对于对联接表列的引用,使用原始值,即使在语句的前面更改了这些联接表列