Mysql 在重复密钥更新时从获取插入/更新行的计数

Mysql 在重复密钥更新时从获取插入/更新行的计数,mysql,sql,on-duplicate-key,Mysql,Sql,On Duplicate Key,我有一条语句试图插入一条记录,如果它已经存在,它只会更新该记录 INSERT INTO temptable (col1,col2,col3) VALUES (1,2,3) ON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3); 完整语句有多个插入,我希望根据更新计算插入的数量。我可以用MySQL变量来实现这一点吗?我在搜索之后还没有找到一种方法来实现这一点。如果你想获得单独插入和更新的记录

我有一条语句试图插入一条记录,如果它已经存在,它只会更新该记录

INSERT INTO temptable (col1,col2,col3)
VALUES (1,2,3)
ON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3);

完整语句有多个插入,我希望根据更新计算插入的数量。我可以用MySQL变量来实现这一点吗?我在搜索之后还没有找到一种方法来实现这一点。

如果你想获得单独插入和更新的记录数,你需要单独发出每个语句。

你应该在查询之后使用
MySQL\u impacted\u rows()

来自

在“INSERT…ON DUPLICATE KEY UPDATE”查询的情况下,如果执行了INSERT,则返回值为1,如果更新了现有行,则返回值为2


使用
mysql\u infected\u rows()
在您的查询之后,如果执行
INSERT
,它将为您提供
1
,如果执行
UPDATE
,它将为您提供
2
我知道这有点旧,但我在PHP中进行了批量插入,需要确切地知道插入和更新了多少行(分别)

所以我用了这个:

$dataCount=count($arrData);//语句中的行数
$infected=mysql\u infected\u rows();//mysqli\u*、PDO的rowCount()或任何东西
$updated=$infected-$dataCount;
$inserted=2*$dataCount-$impacted;
简单跟踪表:

-------------------------------
| data | affected | ins | upd |
-------------------------------
|    1 |        1 |   1 |   0 |
-------------------------------
|    2 |        2 |   2 |   0 |
|    2 |        3 |   1 |   1 |
|    2 |        4 |   0 |   2 |
-------------------------------
|    3 |        3 |   3 |   0 |
|    3 |        4 |   2 |   1 |
|    3 |        5 |   1 |   2 |
|    3 |        6 |   0 |   3 |
-------------------------------
|    4 |        4 |   4 |   0 |
|    4 |        5 |   3 |   1 |
|    4 |        6 |   2 |   2 |
|    4 |        7 |   1 |   3 |
|    4 |        8 |   0 |   4 |
-------------------------------
|    5 |        5 |   5 |   0 |
|    5 |        6 |   4 |   1 |
|    5 |        7 |   3 |   2 |
|    5 |        8 |   2 |   3 |
|    5 |        9 |   1 |   4 |
|    5 |       10 |   0 |   5 |
-------------------------------

我已经使用while循环完成了您描述的内容,因此每次迭代都会创建一个影响一行的MySQL语句。在循环中,我运行MySQL_impact_rows(),然后根据返回的值是0还是1递增一个计数器。在循环结束时,我回显两个变量以供查看

关于mysql\u-infected\u-rows函数的完整措辞是(注意,返回的值可能有3个-0、1或2):

对于INSERT…ON REPLICATE KEY UPDATE语句,受影响的行 如果行作为新行插入,则每行的值为1,如果为 现有行将被更新,如果现有行设置为当前行,则为0 当前值。如果指定客户端\u找到\u行标志,则 如果将现有行设置为“受影响的行”,则“受影响的行”值为1(不是0) 当前值

Sidenote-在while循环之前,我将$countUpdate和$countInsert以及$countUpdateNoChange设置为0):

以下是我开发的代码,对我来说非常有用:

while (conditions...) {    
$sql = "INSERT INTO test_table (control_number, name) VALUES ('123', 'Bob')
    ON DUPLICATE KEY UPDATE name = 'Bob'";  

    mysql_query($sql) OR die('Error: '. mysql_error()); 

    $recordModType = mysql_affected_rows();

    if ($recordModType == 0) {
         $countUpdateNoChange++;
    }elseif($recordModType == 1){
         $countInsert++;
    }elseif($recordModType == 2){
         $countUpdate++;
    };
};

echo $countInsert." rows inserted<br>";
echo $countUpdateNoChange." rows updated but no data affected<br>";
echo $countUpdate." rows updated with new data<br><br>";
while(条件…{
$sql=“插入测试表(控制编号、名称)值('123','Bob')
在重复密钥更新时,名称='Bob';
mysql_query($sql)或die('Error:'.mysql_Error());
$recordModType=mysql_受影响的_行();
如果($recordModType==0){
$countUpdateNoChange++;
}elseif($recordModType==1){
$countInsert++;
}elseif($recordModType==2){
$countUpdate++;
};
};
echo$countInsert.“插入的行数
”; echo$countUpdateNoChange。“行已更新,但数据未受影响
”; echo$countUpdate。“使用新数据更新的行

”;
希望我没有犯任何错误,因为我重新创建了它,以便在删除机密数据时共享


希望这对其他人有所帮助。祝你编码好运!

我认为你的示例查询实际上不会更新任何内容,只是insert,因为在重复键上的
子句中似乎没有你不更新的主键。如果你像示例中那样做,它基本上变成了一个简单的insert。我想你应该在INS上使用触发器吗我精简了示例的代码,但是完整的语句要么是insert要么是update。我只是想知道如何计算要显示给user@ShaunPerry语句将是1,或者它也将有多个insert查询。它是一个insert,有多行。请详细说明您想说什么好吗例如:在重复键上插入可诱惑的(col1,col2,col3)值(1,2,3),(3,2,1),(4,5,6)更新col1=VALUES(col1),col2=VALUES(col2),col3=VALUES(col3);如果记录不是完全重复的:
如果将行作为新行插入,则每行受影响的行值为1;如果更新现有行,则每行受影响的行值为2;如果将现有行设置为其当前值,则每行受影响的行值为0。
但是,如果同时插入两条或多条记录,例如一条记录最终被插入,另一条记录以u结尾,会发生什么情况p被更新了???什么?我不明白。如果数据是,比如说3,受影响的返回为3。你怎么知道它是1 ins+1 upd还是3 ins+0 upd?这两者都会导致3…嗨!看看我发布的表。如果你插入3行并且
mysql\u受影响的\u行()
返回3,不是1 ins和1 upd,因为只有2行,对吗?:恐怕这没有抓住重点。问题是如何解释受影响的行,以区分插入和更新。