【问题标题】:How to return number rows affected on multiple inserts with Mysqli Php?如何使用 Mysqli Php 返回受多个插入影响的行数?
【发布时间】:2020-02-02 06:02:37
【问题描述】:

我有一个函数,它使用带有准备好的语句的 MySqli 库插入多行。插入效果很好,问题是 $stmt->affected_rows 方法中的构建总是将受影响的行数返回为 1。

现在为了解决受影响的行问题,我创建了一个计数器来计算每个执行的语句。这个解决方案是准确的。但是我喜欢使用内置的方法和函数,那么为什么$stmt->affected_rows 总是返回一个,即使我插入了多行?我的代码在某些方面或形式上是否存在缺陷?也许有一个纯Sql的解决方案。

这是我的代码:

try {
    $query = "INSERT INTO dryenrolltb(enroll_id,id_entity,bin_type,tara_weight,dtetime_created,enrollprint_status) VALUES(?,?,?,?,?,?)";
    $stmt = $db->prepare($query);
    $stmt->bind_param('iiidsi', $enroll,$ent,$bin,$tara,$dte_create,$enr_status);
    $result['rows']['rowerrors'] = array();
    $result['rows']['rowsaffected'] = [];
    $cnt = 0;
    foreach ($arr as $value) {
        $enroll = $value['enroll'];
        $ent = $value['entid'];
        $bin = $value['bin_t'];
        $tara = $value['tara'];
        $dte_create = $value['dtecreat'];
        $enr_status = $value['enr_status'];
        if($stmt->execute()) {
            $cnt++;
        } else {
            array_push($result['rows']['rowerrors'],$value['enroll']);
        }

    }
    if ($stmt->affected_rows > 0) {
        echo "Affectionately yours";
        array_push($result['rows']['rowsaffected'], $stmt->affected_rows);
        array_push($result['rows']['rowsaffected'], $cnt);
        return $result;
    } else {
        return false;
    }
} catch (Exception $e) {
    echo "Danger exception caught";
    return false;
}

有人可以告诉我为什么$stmt->affected_rows 总是在多次插入时返回一个吗?

【问题讨论】:

  • 只是上次查询影响的行数,不是累积的。
  • 我不确定我是否理解您的问题,但是您准备好的语句的每次执行只会插入 1 条记录,因此 affected_rows 将始终为 1。我怀疑是否存在任何累积数字,但这是有趣的问题 IMO。
  • 如果您在单个查询中插入多行,而不是为每一行单独查询,它将包含总行数。
  • 使用 PDO 比使用 mysqli 容易得多,因为您可以将所有参数作为数组提供。
  • 恕我直言,everything 使用 PDO 比使用 mysqli 更容易,我不知道为什么 mysqli 使用得更多。可能只是因为它看起来像 mysql,这是多年来的常规 API。

标签: php mysql mysqli sql-insert rows-affected


【解决方案1】:

没有。似乎 MySQLi 语句类无法存储受影响行的运行总数。仔细想了想,觉得很有道理。让我解释一下。

每次执行语句都会影响给定数量的行。在您的情况下,您有一个简单的 INSERT 语句,它将一一添加记录。因此,每次调用 execute() 时,affected_rows 的值都是 1。

查询可能有所不同。例如INSERT INTO ... SELECTUPDATE 可能会影响多行。
你也可以有INSERT INTO ... ON DUPLICATE KEY UPDATE。如果密钥存在于数据库中,那么您没有插入任何内容。如果值相同,您甚至不会更新任何内容。受影响的行,可能是 0 或更多。

语句保持受影响行的运行总数是不明智的,原因是每次执行都会影响某些行,而与之前的执行无关。它们甚至可能是相同的记录。考虑以下示例:

$stmt = $mysqli->prepare('UPDATE users SET username=? WHERE id=?');
$stmt->bind_param('si', $name, $id);

$id = 102;

$name = 'Affected rows 1';
$stmt->execute();
echo $stmt->affected_rows; // 1

$name = 'Affected rows 2';
$stmt->execute();
echo $stmt->affected_rows; // 1

两个更新语句都更新了同一行。如果 mysqli 保持运行总计,它将报告 2 个受影响的行,但实际上只有 1 行被更改。如果将数字相加,您将丢失信息。

因此,对于您的简单场景,您可以自行保留总数,例如在每次执行后汇总 $stmt->affected_rows。除此之外,它可能没有多大意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多