PHP PDO不会在重复键插入时抛出异常


PHP PDO does not throw exception on duplicate key insert

我有一个奇怪的问题,PDO在插入重复值时不抛出异常。在这种情况下,我确实期望出现错误。

相关代码:

try
{
  $db_conn = new PDO("mysql:host=".$config["database"]["hostname"].";charset=utf8", $config["database"]["username"], $config["database"]["password"], []);
  $db_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $db_conn->exec(file_get_contents("some_file_with_data.sql");
}
catch(Exception $e)
{
  // PDOException extends RuntimeException extends Exception so exceptions should be catched here
  // however for the duplicate key entry it will not throw an exception
}
包含SQL数据的文件包含多个插入,如下所示:
INSERT INTO `a` (`b`, `c`) VALUES
  (1, 1),
  (2, 2),
  (3, 2);
INSERT INTO `a` (`b`, `c`) VALUES
  (1, 1);

将表a中的字段b设置为主键。当我使用phpMyAdmin在完全相同的结构中插入完全相同的数据时,我得到这个错误:#1062 - Duplicate entry '65533' for key 'PRIMARY'

为什么PDO在这种情况下不抛出错误?即使我将错误模式设置为异常?

编辑:这是用于这个特定表

的表结构。
CREATE TABLE IF NOT EXISTS `a` (
  `b` smallint(5) unsigned NOT NULL,
  `c` smallint(5) unsigned NOT NULL,
  PRIMARY KEY (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

2018年更新:开发人员不认为这是一个bug,而是预期的行为。因此,php用户必须忍受这一点,报告已关闭,任何未来的问题…

这经常被报告为PDO的bug: https://bugs.php.net/bug.php?id=61613

它只会在FIRST语句无效时抛出异常。如果第一个语句运行顺利,您将不会得到任何错误-并且您的第一个语句有效:

INSERT INTO `a` (`b`, `c`) VALUES
  (1, 1),
  (2, 2),
  (3, 2);

作为一种解决方法——或者根据用户删除的正确方法——您需要一个接一个地处理行集(取自bug报告注释):

$pdo->beginTransaction();
try {
    $statement = $pdo->prepare($sql);
    $statement->execute();
    while ($statement->nextRowset()) {/* https://bugs.php.net/bug.php?id=61613 */};
    $pdo->commit();
} catch ('PDOException $e) {
    $pdo->rollBack();
    throw $e;
}