0

我有一个表,其列必须具有 UNIQUE 值(但它也可能是多列 UNIQUE 索引,问题是一样的)。在我的 PHP 脚本中,我必须在该表中插入一行。

如果出现问题,我正在寻找一种方法,而不是 MySQL 特定的方法来退出 PHP 脚本,并且问题违反 UNIQUE 约束。为了让事情变得更简单,我不想在 :D 之前使用 SELECT 查询

目前我正在做这样的事情:

try
{
    $stmt = $dbh->prepare($someinsertquery);
    $stmt->bindParam(':somecol', $somecol);

    $stmt->execute();
}
catch (PDOException $e)
{
    $errcode = $e->getCode();

    if (! ($e->getCode() === '23000'))
    {
        echo 'Error inserting into db: ' . $e->getMessage();
        var_dump($e->getTrace());

        exit();
    }
}

问题是这样我也错过了与外键相关的错误。我认为如果我在插入新行时不会出现外键问题,那没关系,但如果我将来更改表怎么办?我可以使用

PDOStatement::errorInfo[1]

但它是特定于驱动程序的错误代码。与 ON DUPLICATE KEY UPDATE 相同。

4

3 回答 3

2
$someinsertquery = "INSERT IGNORE INTO table SET somecol=?";
$stmt = $dbh->prepare($someinsertquery);
$stmt->execute(array(($somecol)));
if ($stmt->rowCount()) {
    //everything is okay
}

请注意所有这些 try..catch..echo..exit 的东西都被故意省略了,因为它在这里完全没用。

于 2013-05-22T16:47:51.267 回答
0

要么就是这样,要么在插入之前进行选择,看看是否会在任何唯一索引上发生冲突。

于 2013-05-22T15:49:23.067 回答
0

实际上并没有一种与数据库无关的方法来捕获 SQL 错误。

SQL 标准将 SQLSTATE 定义为两个字符的类,后跟一个三字符的子类。标准定义了一些两字符类;其他由实现定义。

标准将两字符类“23”定义为“违反完整性约束”。他们只为“23”定义了一个子类。它是'001',意思是“限制违规”。但实现方式各不相同。尽管 MySQL 显然只定义了 '23000',但PostgreSQL为 '23'定义了至少六个不同的子类。(PostgreSQL 子类将外键违规与唯一违规区分开来。)

因此,了解 SQLSTATE '23000' 的 MySQL 含义的唯一方法似乎是查看MySQL 错误代码。错误 1022 表示“重复密钥”;1216 和 1217 与外键约束有关。

查看各种数据库“连接器”的源代码以了解它们是如何实现的可能会很有用。php源代码在线。(我希望这包括 PDO。)ruby​​ 的 ActiveRecord也是如此。

于 2013-05-22T17:59:39.273 回答