Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL-如何在重复密钥更新查询中对批量插入中的插入和更新进行计数?_Mysql - Fatal编程技术网

MySQL-如何在重复密钥更新查询中对批量插入中的插入和更新进行计数?

MySQL-如何在重复密钥更新查询中对批量插入中的插入和更新进行计数?,mysql,Mysql,我有一个MySQL查询,它执行批插入,并在重复密钥更新时使用它来更新行,以防出现唯一的重复密钥 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); 换

我有一个MySQL查询,它执行批插入,并在重复密钥更新时使用它来更新行,以防出现唯一的重复密钥

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将被更新


查询完成后,我想知道插入了多少行以及更新了多少行。这可能吗?

添加一个新列,例如blabla,并将其作为默认值设置为null。 我想你只会用一次

然后


不,没有明确的方法从受影响的
行数中判断。有一些角落的案例我们可以告诉你。。。如果受影响的行数恰好是我们尝试插入的行数的两倍,则我们知道它们都是更新。如果受影响的
rows\u
计数为零,则我们知道没有插入任何行。如果受影响的
行数为1,则我们知道插入了一行。但除此之外,还有很多排列

可以在插入
之前手工编写
,在更新
之前手工编写
触发器,以增加用户定义的变量。如果我们在插入之前立即初始化用户定义的变量。。。在DuplicateKeyUpdate语句中,我们可以组合使用这些变量来确定尝试插入的行数,以及其中有多少行导致了重复键异常。(MySQL不会增加受影响的
行数
,因为更新操作不会导致实际的行更新。)


编辑

如果您保证更新操作将导致行的实际更改。。。如果要更改每行上至少一列的值,则对于更改的每一行。。。如果您有一个要插入的实际行数的计数,那么您可以根据受影响的行数确定插入了多少行,以及更新了多少行

插入。。。ON DUPLICATE键可导致插入和更新同一行,和/或导致同一行更新多次


您是要统计“更新”操作的数量,包括对同一行的更新,还是要统计表中已更新的行数

扩展hakkikonu的答案,并先阅读它,否则这将毫无意义,如果它真的

并同意@spencer7593的评论,比如“带锁的并发杀死(CK)操作”, 需要修正确定hak答案中更新计数的公式

我认为没有CK就无法获得准确的插入和更新计数。扣动扳机后投球 如果没有CK,“单独且同时准确”,肯定无助于解决问题

我们的table1.blabla列仅用于针对table1的批处理,而不考虑频率 这批货中的一批。如果批处理未针对表1运行,则即使未删除该列,blabla也保证为null。这是显而易见的

我相信你可以得到插入和更新计数 准确地说。以下是如何使用Insert语句并基于Insert语句

表1为批处理代码提供了独占的写锁。让我们假设MyISAM存储引擎。嘿,为什么不呢,我们 我们在这里做假设。 blabla列根据您的语句显示null“inserted”和“updated”(和Hakkikonu建议的几乎没有什么不同)。 你有你的计数

关于spencer在其回答中所写的关于给定行基于 你的问题是插入语句,我不这么认为。除非您的批处理数据显示了重复的键,否则在这种情况下,准确性到底有什么关系

行是否存在取决于在重复键上抛出的内容。如果它抛出了它,这是一个更新, 如果没有,请插入。有人纠正我

然后在最后执行alter table drop blabla或更新为null。锁已释放


所以我猜更新和插入计数、表的大小和批处理的频率有多重要。

聪明的方法。示例查询没有得到正确的计数,这些需要修改。我们实际上可以在一个查询中获得计数。在运行语句之前,我们确实需要获得相同的计数,并且我们必须假设在会话执行操作时,没有其他会话对表执行任何DML操作。为了保证这一点,我们需要在表上引入杀死并发的锁(以防止其他会话在我们的操作运行时进行更改)!我最终使用了两个不同的“blabla”列,它们具有不同的nonce值,然后在进程结束时查询count()这些值。我使用的是InnoDB,在本例中,我没有锁定表,因为在作业运行时,任何其他进程都不太可能修改我的“blabla”列。感谢您富有洞察力的回答和评论。在这种情况下,它是一个复合键;因此,我认为不太可能对同一行进行多次更新或插入。使用该示例,唯一键是col1+col2,因此我认为要么更新col3(如果col1+col2匹配),要么将整个值集作为新行插入。@billrichards:在更一般的情况下,完全可以运行
INSERT。。。在具有
值(1,1,1)、(1,1,1)、(1,1,2)、(1,1,1)、(1,1,1)、(1,1)、(1,1),…)的重复键上执行
语句
。这样做是完全正确的。这就是为什么在更一般的情况下,不可能使用“受影响的行”计数来确定插入了多少行以及更新了多少行的原因。正是这种普遍性,op应该认真检查批处理数据的构造。并为sa做相应的准备
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