【问题标题】:SQLSTATE[23000]: Integrity constraint violation error handlingSQLSTATE[23000]:完整性约束违反错误处理
【发布时间】:2014-07-21 08:42:55
【问题描述】:

我知道错误的含义以及它发生的原因,这意味着这不是涵盖状态 23000 的许多主题的重复。我正在使用 PDO 将重复记录插入到具有复合 PK 的表中。我是故意这样做的,以便自动取消将任何重复记录插入到此特定表中。

错误SQLSTATE[23000]: Integrity constraint violation 正在杀死脚本。有没有办法为这个特定错误设置警告级别,告诉它闭嘴并继续?

如果我们不能让复合 PK 为我们工作,我就不明白它们的目的是什么?

我对数据库管理不是很有经验,所以如果我遇到“如果我用锤子敲它应该可以工作”的话,你必须原谅我。

表结构:

CREATE TABLE `cart` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `userid` int(10) NOT NULL,
 `itemid` int(10) NOT NULL,
 UNIQUE KEY `id` (`id`),
 UNIQUE KEY `unique_records` (`userid`,`itemid`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1

注意称为“唯一记录”的复合 PK。

所以我有这张桌子:

| id | userid | itemid |
|  1 |    175 |     12 |

然后我执行这个查询:

    $insertItem = $db->query("
                              INSERT INTO cart (userid, itemid) 
                              VALUES (:userid, :itemid), 
                              array("userid"=>"175", "itemid"=>"12")
                            ");

执行此查询提示此错误:SQLSTATE[23000]: Integrity constraint violation

我完全理解为什么会收到此错误 - 我只是不明白为什么它会杀死我的提交?我认为它应该继续工作,忽略一些记录因为重复而没有插入的事实?

建议!

【问题讨论】:

    标签: mysql sql pdo duplicates


    【解决方案1】:

    您的问题似乎很含糊 - 要么您想忽略违反完整性约束的行为,要么您希望它们成为“不再插入”的信号。

    除了insert ignore 解决方案的答案 - 当您执行查询并收到SQLSTATE[23000]: Integrity constraint violation 错误时,这意味着 PDO 抛出异常。如果你不catch 它,你的脚本就会被杀死。如果您不希望它被杀死,请将您的数据库代码包装到 try-catch 构造中,即:

    try {
        // code here
        $insertItem = $db->query("
                                  INSERT INTO cart (userid, itemid) 
                                  VALUES (:userid, :itemid)", 
                                  array("userid"=>"175", "itemid"=>"12")
                                );
        // more code here
    } catch(Exception $e) {
        // handle exception - 
        // find out if it is caused by integrity contraints violations
        // and if it is - merely go further
        // otherwise do something else, like re-throwing your exception
    }
    

    HTH

    【讨论】:

    • +1 我刚刚了解到,如果您发现错误,它们不会杀死您的脚本。老实说,我不知道这一点:) 谢谢!
    • 问题是如何检测它是否是由违反完整性约束引起的?我知道是这样,但我不确定 if 语句会是什么才能看到它正是违反
    • @iBobb 我想到的最简单的事情 - 制作一个测试脚本和 var_dump 异常变量 $e - 它应该包含一些代码或 SQL 状态,表示你有“完整性约束违规” -见上面的“SQLSTATE[23000]:完整性约束违规”,所以大概它会包含“23000”作为错误代码
    • 我四处搜索并这样做了:catch (PDOException $e) { if ($e->getCode() != 23000) { $status = "status 0" . $e; } else { $status = "status -1"; }
    【解决方案2】:

    如果您希望insert 继续工作,您可以尝试使用INSERT IGNORE

    INSERT IGNORE INTO cart(userid, itemid) 
        VALUES (:userid, :itemid);
    

    INSERT IGNORE 可能有点强,因为它会忽略所有错误。如果您只想忽略重复键错误,请使用on duplicate key 并为其自身设置一个值:

    INSERT IGNORE INTO cart(userid, itemid) 
        VALUES (:userid, :itemid)
        ON DUPLICATE KEY userid = values(userid);
    

    set 部分什么都不做——值没有改变——但效果是忽略错误。

    【讨论】:

    • 我很喜欢这个,之前没用过IGNORE,谢谢! +1
    猜你喜欢
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 2015-03-19
    • 2015-11-27
    • 2017-09-11
    • 2015-01-20
    • 2015-07-17
    相关资源
    最近更新 更多