Игнорировать дубликат ключа при вставке с PDO - PullRequest
3 голосов
/ 28 июня 2011

Существует ли общий способ 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;
}

Ответы [ 2 ]

2 голосов
/ 28 июня 2011

AFAIK нет, не существует универсальной версии, которая будет работать со всеми драйверами базы данных. INSERT IGNORE и INSERT...ON DUPLICATE KEY UPDATE относятся к MySQL.

Проверка существующей записи путем ее первого выбора или удаления существующей записи и повторной вставки являются склонными к проблемам, включая состояние гонки и возможные нарушения ограничений внешнего ключа или каскадное удаление.

Я думаю, что ваш подход, вероятно, самый безопасный. Вы всегда можете проверить код ошибки , если хотите определить причину исключения - см .:

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

Я думаю, вы можете проверить код 23000.

1 голос
/ 28 июня 2011

Ваш код, вероятно, будет работать, но есть другие вещи, которые могут пойти не так при выполнении оператора PDO.Вы захотите проверить, действительно ли вы получили нарушение ограничения, и даже если это не другой тип (например, вы также можете получить нарушение внешнего ключа при вставке пары значений, у которых нет соответствующих строк в одном изссылочные таблицы).AFAIK, кросс-СУБД не существует способа достичь этого, хотя.

Для СУБД, поддерживающих транзакции (Oracle, SQL Server, PostgreSQL, MySQL в некоторой степени ...), вот другой подход:

  1. начало транзакции
  2. удаление всех строк, соответствующих вставляемой строке (удаление нуля или одной строки)
  3. insert
  4. commit
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...