如何在ON DUPLICATE KEY UPDATE查询后知道行是否已更新或插入

时间:2014-10-28 21:30:09

标签: php mysql pdo

我需要插入表格或更新值。

我需要知道数据是否已更新或新创建。

目前我的逻辑是SELECT,如果不存在INSERT,如果存在UPDATE

我需要计算更新的行数和插入的行数。

这很慢,我需要更快的方法:我可以使用INSERTREPLACE而不尝试先选择,并让PDO客户端返回该行是否已更新或插入?

我正在使用PHP / PDO / MySQL

使用伪代码

更新

当前逻辑:

<?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

4 个答案:

答案 0 :(得分:0)

我正在使用MariaDB(或MySQL,如果您愿意的话),并且正在寻找该问题的解决方案,并且遇到了这篇文章。它部分地回答了这个问题,但并没有完全解决我要达到的目标。当我从DanFromGermany读到的时候,这个问题是:在我进行一次或多次事务处理时,有多少记录添加到数据库中,而数据库中更新了多少记录。

因此,使用本文中的一些有用元素,我提出了以下解决方案: 在我的实际代码中,我已将其全部包装在需要的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;

答案 1 :(得分:-1)

如果您使用ON DUPLICATE KEY UPDATE,则可以剪切一步(SELECT)。所以它只是一个查询。

以下是文档:

http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

至于检查,这是代码:

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';
}

答案 2 :(得分:-1)

如果您的表有PRIMARY KEY或UNIQUE索引,则需要REPLACE INTO。

答案 3 :(得分:-1)

如果您的表具有主键或唯一索引,

http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html将执行此操作。

假设您有一个包含列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);

将在找到主键后更新。