Проверьте, существует ли запись перед вставкой - PullRequest
3 голосов
/ 15 декабря 2009

У меня есть скрипт php для вставки новых деталей в базу данных postgres. Я хочу проверить, существует ли часть, прежде чем она будет создана. Как я могу это сделать. Я использую обычное предложение INSERT INTO.

Ответы [ 3 ]

6 голосов
/ 15 декабря 2009

Сначала SELECT, чтобы узнать, нужно ли INSERT или UPDATE, например:

if (
    $db->fetchOne(
        'SELECT COUNT(1) FROM parts WHERE article_number = ?',
        $p->article_number
    )
) {
    $db->update(
        'parts',
        $p->to_array(),
        $db->quoteInto('article_number = ?', $p->article_number)
    );
}
else {
    $db->insert('parts', $p->to_array());
}

Комментарий Ре Милена: отличный момент! При уровне изоляции транзакций PostgreSQL по умолчанию (READ COMMITTED) возможно, что другой процесс вставит (и подтвердит) "вашу" часть после вашей SELECT, но до вашей INSERT.

Для приложений, которые мы создаем, мы обычно просто перехватываем исключение из БД и что-то предпринимаем (сообщите пользователю, повторите попытку). Или вы можете пойти с SET TRANSACTION ISOLATION LEVEL SERIALIZABLE. См. Изоляция транзакции .

5 голосов
/ 16 декабря 2009
insert into parts(article_number,category) 
select 'KEYB','COMPTR' 
where not exists(select * from parts where article_number = 'KEYB')
2 голосов
/ 16 декабря 2009

Если вы редко ожидаете конфликтов: используйте оптимистический подход и просто вставьте новый и обработайте нарушение уникальности, если оно произойдет. Это приведет к аннулированию текущей транзакции, если она потерпит неудачу, поэтому, если вы выполняете в ней много работы, стоит сначала проверить ее. В этом случае я предпочитаю SELECT EXISTS(SELECT 1 ... FROM ... WHERE ...).

В любом случае, вы должны обработать возможность нарушения уникальности. Даже если вы сначала проверите, есть вероятность, что параллельная транзакция вставит ту же запись и зафиксирует сначала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...