简体   繁体   中英

Check is record exists before inserting

I have a php script to insert new parts into a postgres database. I want to check if the part exists before it is created. How can I do this. I am using the usual INSERT INTO clause.

You SELECT first, to know if you must INSERT or UPDATE , like:

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());
}

Re Milen's comment: great point! With the default PostgreSQL transaction isolation level ( READ COMMITTED ) it's possible that another process inserts (and commits) "your" part after your SELECT , but before your INSERT .

For the kind of apps we build, we normally just catch the DB exception, and do something about it (inform the user, retry). Or you can go with SET TRANSACTION ISOLATION LEVEL SERIALIZABLE . See Transaction Isolation .

insert into parts(article_number,category) 
select 'KEYB','COMPTR' 
where not exists(select * from parts where article_number = 'KEYB')

If you rarely expect conflicts: Take the optimistic approach and just insert the new one and handle the uniqueness violation if it occurs. This will invalidate the current transaction when it fails, so if you're doing a lot of work in it, it'll be worthwhile to check first. In that case, I prefer SELECT EXISTS(SELECT 1 ... FROM ... WHERE ...) .

Anyway, you must handle the possibility for a uniqueness violation. Even if you check first, there is a possibility that a concurrent transaction inserts the same record and commits first.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM