Php 如何知道在重复键更新查询之后是否更新或插入了行
我需要插入到表中或更新值 我需要知道数据是更新的还是新创建的 目前我的逻辑是选择,如果不存在插入,如果存在更新 我需要计算更新的行数和插入的行数 这很慢,我需要一种更快的方法:我可以使用INSERT或REPLACE而不首先尝试选择,并让PDO客户端返回行是更新了还是插入了 我正在使用PHP/PDO/MySQL 使用伪代码更新: 当前逻辑:Php 如何知道在重复键更新查询之后是否更新或插入了行,php,mysql,pdo,Php,Mysql,Pdo,我需要插入到表中或更新值 我需要知道数据是更新的还是新创建的 目前我的逻辑是选择,如果不存在插入,如果存在更新 我需要计算更新的行数和插入的行数 这很慢,我需要一种更快的方法:我可以使用INSERT或REPLACE而不首先尝试选择,并让PDO客户端返回行是更新了还是插入了 我正在使用PHP/PDO/MySQL 使用伪代码更新: 当前逻辑: <?php $rowExists = PDO SELECT by key if ($rowExists) PDO UPDATE by key
<?php
$rowExists = PDO SELECT by key
if ($rowExists)
PDO UPDATE by key
$updates++
else
PDO INSERT
$inserts++
通缉逻辑:
<?php
PDO INSERT .. ON DUPLICATE KEY
$updates++ or $inserts++ according to what it actually did
如果在重复密钥更新中使用,则可以剪切一步选择。因此,这将只是一个查询 以下是文件: 至于检查,代码如下:
if($stmt->rowCount() > 0 ){
if($stmt->lastInsertId() != 0){
echo 'Row was inserted';
}else{
echo 'Row was updated';
}
}else{
echo 'row was neither updated or inserted';
}
如果表有主键或唯一索引,则需要替换为。如果表有主键或唯一索引,则需要替换为 假设您有一个id列为主键a和b的表,并且有一条记录1,2,3。id=1有了新的值,即a=4和b=5,但不想检查id=1是否已经存在条目 INSERT (id, a, b) VALUES (1, 4, 5) ON DUPLICATE KEY UPDATE a = VALUES(a), b = VALUES(b);
将在找到主键后更新。如果您愿意,我正在使用MariaDB或MySQL,并且正在寻找此问题的解决方案,因此我看到了这篇文章。它部分地回答了这个问题,但没有完全解决我想要达到的目标。我从德国Danfrom读到的问题是:在我的一个或多个事务中,有多少记录被添加到数据库中,有多少记录被更新到数据库中 因此,利用本文中的一些有用元素,我提出了以下解决方案: 在我的实际代码中,我将其全部包装在try/catch中,并假设$dbx是一个实例化的PDO mysql数据库对象
/*
Get the current table row count
(it's our starting point, so any inserted row will increase the count)
*/
$stmt = $dbx->query("SELECT COUNT(*) FROM `destination_table`");
$row = $stmt->fetch(PDO::FETCH_NUM);
$startCount = $row[0];
$stmt = null;
/*
Set an iteration counter
(
I was using a prepared statement looping through
INSERT / ON DUPLICATE KEY UPDATE, so want to check each loop for any change
)
*/
$countAnAction = 0;
/*
Prepare the INSERT with ON DUPLICATE KEY UPDATE for each line to process
(assuming `a` is the key, regardless of type)
*/
$stmt = $dbx->prepare("
INSERT INTO `destination_table` (`a`,`b`)
VALUES(:a, :b1)
ON DUPLICATE KEY UPDATE `b` = :b2
");
$stmt->bindParam('a', $a, PDO::PARAM_STR);
$stmt->bindParam('b1', $b, PDO::PARAM_STR);
$stmt->bindParam('b2', $b, PDO::PARAM_STR); # set update value if a exists
// Assume we have an associative array of 'a', 'b' values passed to process
foreach($inputRowToProcess as $arrVals)
{
# Set our prepared values from the array elements
$a = $arrVals['a'];
$b = $arrVals['b'];
$stmt->execute();
/* Now check if something happened and increment $countAnAction
(
$stmt->rowCount() on MySQL can be 1 or 2, depending on the action
based off a value greater than zero, update the row count by 1
)
*/
if($stmt->rowCount() > 0)
{
$countAnAction += 1;
}
}
$stmt = null;
// Now we get the count of rows in the destination table after the process has finished
$stmt = $dbx->query("SELECT COUNT(*) FROM `destination_table`");
$row = $stmt->fetch(PDO::FETCH_NUM);
$endCount = $row[0];
$stmt = null;
// Finally apply some math to the various elements to determine inserted count and updated count
$insertedRows = $endCount - $startCount;
$updatedRows = ($endCount - $startCount) + $countAnAction;
有插入。。。关于重复密钥update@MarcB我知道,但它能告诉我是更新了还是插入了吗?请使用伪代码查看我的更新问题。如果插入了该问题,则最后一个插入id将具有该新行的新id。但这只适用于一次插入。如果您使用的是扩展插入语法或插入。。。从中选择,然后所有赌注都被取消。@YourCommonSense很好,现在您将问题指向一些旧的mysql答案。。。。。非常有用..我如何知道它是否真的插入或更新了?@DanFromGermany检查$stmt->lastInsertId,如果没有插入任何内容,例如$stmt->lastInsertId>0inserted':'updated'@DanFromGermany see my Update这只适用于自动递增键,当我在插入前有PK时它就不起作用了:/什么不起作用?请你解释一下,你在这里犯了一个非常常见的错误,假设这个站点总是只有一个用户。但是,很显然,情况不会如此。因此,任何并发进程都可能完全破坏您的数学。此外,如果密钥存在并且执行了更新,$stmt->rowCount=1,则您的这种假设是完全错误的。感谢您的常识,您认识到了上述rowCount假设的缺陷,并已恢复正确。此外,表锁定似乎解决了我添加行的特定“用例”中的数学问题。我没有在我的工作中加入这些台词。在这里发帖还是新鲜事,所以我也应该更新一些东西吗?我认为这一点都不重要,因为目标可以通过一个简单的条件实现,如链接的答案所示。而桌面锁定是一个非常危险的游戏,应该避免