我有一个奇怪的问题,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
}
Run Code Online (Sandbox Code Playgroud)
带有SQL数据的文件包含多个这样的插入:
INSERT INTO `a` (`b`, `c`) VALUES
(1, 1),
(2, 2),
(3, 2);
INSERT INTO `a` (`b`, `c`) VALUES
(1, 1);
Run Code Online (Sandbox Code Playgroud)
b表中的字段a设置为主键.当我使用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;
Run Code Online (Sandbox Code Playgroud)
这通常被报告为bug PDO:https://bugs.php.net/bug.php?id = 61613
如果FIRST语句无效,它只会抛出异常.如果第一个语句运行顺利,您将不会收到任何错误 - 并且您的第一个语句有效:
INSERT INTO `a` (`b`, `c`) VALUES
(1, 1),
(2, 2),
(3, 2);
Run Code Online (Sandbox Code Playgroud)
作为一种解决方法 - 或根据您的常识,正确的方法 - 您需要逐个处理行集(取自错误报告评论):
$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;
}
Run Code Online (Sandbox Code Playgroud)