【发布时间】:2018-11-26 08:21:33
【问题描述】:
我有以下代码来更新 MariaDB 表中的一行:
<?php
$statement = <<<SQL
UPDATE `my_table`
SET
`my_name` = :my_name,
`my_id` = LAST_INSERT_ID(my_id)
WHERE `my_id` = :my_id;
SQL;
try {
$sth = $this->dbh->prepare($statement);
$sth->bindValue(':my_name', 'Foo');
$sth->bindValue(':my_id', 12, PDO::PARAM_INT);
$sth->execute();
if ($this->dbh->lastInsertId() == 0) {
echo 'Id not found!';
}
} catch (\PDOException $e) {
echo 'Transaction failed!';
}
我的 SET 子句中的 my_id = LAST_INSERT_ID(my_id) 部分将 Maria DB 的 LAST_INSERT_ID() 的值设置为更新行的 `my_id` 的值。
在我的 sql 客户端中执行 SELECT LAST_INSERT_ID(); 确认该值已设置(结果 = 12)。
在 php 中,我使用PDO::lastInsertId 来获取这个值,如果它为 0,则不存在匹配的行。通过这种方式,我可以区分“my_id 不存在”错误和无提示的 UPDATE(以及所有其他事务错误)。
这在 PHP 5.6.23/MariaDB 10.1.13 中运行良好,但现在我在 PHP 7.2.11/MariaDB 10.1.36 并且PDO::lastInsertId 的返回值保持为零,而该行确实已更新。
PDO::lastInsertId 的行为在这些版本之间是否发生了变化?
这是某种错误吗?
代码之前是否意外运行,但它包含错误或其他内容?
感谢您的回复。
编辑:我可以确认代码仍然适用于 PHP v7.1.8
【问题讨论】:
-
为什么不使用
PDOStatement::rowCount()来获取受影响的行? -
@Dormilich 因为
PDOStatement::rowCount()在行数据没有有效更改时返回 0。 (更新数据与已存储的数据相同。) -
知道更新是否产生匹配重要吗?我认为这对于读取操作是有意义的,但对于更新,我认为没有必要。
-
假设用户想要编辑资产,但在编辑时,另一个用户从 dB 中删除了该资产。
PDO::execute将静默执行语句(PDO::rowCount将为 0),即使 id 不再存在于 dB 中。如果资产不再存在,我想将其报告给用户以避免他感到惊讶,他的更改没有应用,资产似乎反而丢失了。我在以前的代码版本中使用了多个语句来实现这一点,但后来将其转换为单个语句,直到现在都运行良好。