我有一个执行批量INSERT的MySQL查询,并使用ON DUPLICATE KEY UPDATE来更新行,以防有唯一的密钥重复。
INSERT INTO table1
(col1,col2,col3)
VALUES
(val1,val2,val3),
(val4,val5,val6),
(val7,val8,val9),
...
(valn,valx,valz)
ON DUPLICATE KEY UPDATE
col3 = VALUES(col3);
换句话说,除非存在重复的唯一键,否则会插入新行,在这种情况下会更新col3。
查询完成后,我想知道INSERTED有多少行以及UPDATED有多少行。这可能吗?
答案 0 :(得分:2)
不,从rows_affected
计数中没有明确的判断方法。我们可以告诉一些极端情况......如果rows_affected正好是我们尝试插入的行数的两倍,我们知道它们都是更新。如果rows_affected
计数为零,我们知道没有插入任何行。如果rows_affected
计数为1,我们知道插入了一行。但除此之外,还有很多排列。
有可能制作BEFORE INSERT
和BEFORE UPDATE
触发器来增加用户定义的变量。如果我们在INSERT ... ON DUPLICATE KEY UPDATE语句之前立即初始化用户定义的变量,我们可以组合使用这些变量来确定我们尝试插入的行数,以及这些行中有多少导致重复键异常。 (对于没有对该行进行实际更新的UPDATE操作,MySQL不会增加rows_affected
。)
修改强>
如果您保证UPDATE操作将导致对行的实际更改...如果您要更改每行上至少一列的值,对于每个更改的行...以及如果您计算您尝试插入的实际行数,然后您可以从rows_affected中确定插入了多少行,以及更新了多少行。
INSERT ... ON DUPLICATE KEY可以导致插入和更新同一行,和/或导致同一行多次更新。
您是否需要计算“更新”操作的数量,包括对同一行的更新,或者您是否希望计算更新的表中的行数?
答案 1 :(得分:2)
扩展hakkikonu的答案,并先阅读它,否则根本就没有意义......
并同意@ spencer7593的评论,例如"使用lock"进行并发查杀(CK)操作, 并且需要在hak的答案中确定用于确定更新计数的公式
我认为如果没有CK,我无法获得准确的插入和更新计数。投掷AFTER触发器 肯定没有帮助解决它没有 CK,"单独并且同时准确"。
是一个可以为null的table1.blabla列,只用于对table1的批处理,无论频率如何 这些批次。如果批处理没有针对table1运行,则即使未删除该列,也保证blabla为null。这是显而易见的。
我相信你可以获得插入和更新计数 准确。这是基于您的Insert语句的方式。
table1具有专用于批处理代码的写锁定。让我们假设MyISAM存储引擎。嘿,为什么不,我们 在这里做出假设。 blabla列显示null' inserted'并且'更新了'根据你的陈述(与Hakkikonu建议的几乎不同)。 你有自己的数量。
关于spencer在他的答案中写的关于基于的给定行的更新和/或插入不止一次的内容 你的问题的插入声明,我不这么认为。除非您的批次数据中包含重复的密钥,否则无论如何,准确性至关重要。
根据打开ON DUPLICATE KEY的内容,行是否存在开头。如果它扔了它,它是一个更新, 如果没有,请插入。有人纠正我。
然后在结束时执行alter table drop blabla或更新为null。锁被释放。
所以我想更新和插入计数,表的大小以及批次的频率有多重要。
答案 2 :(得分:0)
添加一个类似 blabla 的新列,并将其作为默认值提供null。 我假设,你只会使用一次。
然后
ON DUPLICATE KEY UPDATE
col3 = VALUES(col3),
blabla = 'up' ;
SELECT count(blabla) as allrows FROM table1; # returns all rows count
SELECT count(blabla) as updrows FROM table1 WHERE blabla = 'up'; # returns update count
SELECT count(blabla) as insrows FROM table1 WHERE blabla IS NULL; # returns inserts