2015-09-16 83 views
9

抛出例外,我有当插入一个重复的值PDO不是抛出一个异常奇怪的问题。在这种情况下,我确实希望有一个错误。PHP 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; 
+0

http://stackoverflow.com/questions/11102644/pdo-exception-questions-how-to-catch-them –

+0

我已经把它放在try/catch块中,让我更新我的代码来澄清这一点。 – Matthijs

+0

桌子上设置的确切约束是什么? – deceze

回答

8

表结构这通常被报告为错误与PDOhttps://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; 
} 
+1

非常感谢!我并不完全确定我的代码是100%正确的,但我从来没有发现这个错误报告(如果您没有在重复条目上发生异常,那么他将搜索“如果组中的第一条SQL语句有效,则不会发生PDO错误: P) – Matthijs