使用 PDO 插入时忽略重复键

Posted

技术标签:

【中文标题】使用 PDO 插入时忽略重复键【英文标题】:Ignore duplicate key upon insert with PDO 【发布时间】:2011-09-24 06:51:29 【问题描述】:

有没有一种通用的方法来INSERT IGNORE 使用 PDO,它适用于所有数据库驱动程序?

如果不是,是否可以假设以下方法可行:

try 
    $stmt = $db->prepare("INSERT INTO link_table (id1, id2) VALUES (:id1, :id2)");
    $stmt->execute(array( ':id1' => $id1, ':id2' => $id2 ));

catch (PDOException $ex) 
    // Thanks to comment by Mike:

    // Re-throw exception if it wasn't a constraint violation.
    if ($ex->getCode() != 23000)
        throw $ex;

【问题讨论】:

@Haim Evgi 从我读到的INSERT IGNORE INTO 是一个非标准的 SQL 功能,只适用于 mysql 【参考方案1】:

AFAIK 不,没有适用于所有数据库驱动程序的通用版本。 INSERT IGNOREINSERT...ON DUPLICATE KEY UPDATE 特定于 MySQL。

通过首先选择现有记录来检查现有记录,或者删除现有记录并重新插入都容易出现问题,包括竞争条件和可能违反外键约束或级联删除。

我认为您的方法可能是最安全的。如果您想确定异常的原因,您可以随时check the error code - 请参阅:

http://docstore.mik.ua/orelly/java-ent/jenut/ch08_06.htm

我想你可能想检查一下代码 23000。

【讨论】:

【参考方案2】:

您的代码可能会工作,但在执行 PDO 语句时可能会出现其他问题。您将需要检查您是否真的收到了约束违规,即使它不是另一种类型(例如,当您在其中一个中插入一对没有对应行的值时,您也可能收到外键违规参考表)。 AFAIK,虽然没有跨 DBMS 的方式来实现这一点。

对于支持事务的 DBMS(Oracle、SQL Server、PostgreSQL、MySQL 在某种程度上...),这里有一种不同的方法:

    开始交易 删除与要插入的行匹配的所有行(删除零或一行) 插入 提交

【讨论】:

以上是关于使用 PDO 插入时忽略重复键的主要内容,如果未能解决你的问题,请参考以下文章

使用 PDO 插入时获取自动递增行 ID [重复]

PDO 在条件不工作的情况下插入到重复键中

Python SQLAlchemy 批量插入时忽略重复键

Python SQLAlchemy 批量插入时忽略重复键

忽略插入违反重复键索引的行

如何使用 insert_many 安全地忽略重复的键错误