Search code examples
sqloracleoracle-sqldeveloper

Insert if not exists Oracle


I need to be able to run an Oracle query which goes to insert a number of rows, but it also checks to see if a primary key exists and if it does, then it skips that insert. Something like:

INSERT ALL
    IF NOT EXISTS( SELECT 1 WHERE fo.primary_key='bar' )
    (
        INSERT INTO 
            schema.myFoo fo ( primary_key, value1, value2 )
        VALUES
            ('bar','baz','bat')
    ),
    
    IF NOT EXISTS( SELECT 1 WHERE fo.primary_key='bar1' )
    (
        INSERT INTO 
            schema.myFoo fo ( primary_key, value1, value2 )
        VALUES
            ('bar1','baz1','bat1')
    )
SELECT * FROM schema.myFoo;

Is this at all possible with Oracle?

Bonus points if you can tell me how to do this in PostgreSQL or MySQL.


Solution

  • The statement is called MERGE. Look it up, I'm too lazy.

    Beware, though, that MERGE is not atomic, which could cause the following effect (thanks, Marius):

    SESS1:

    create table t1 (pk int primary key, i int);
    create table t11 (pk int primary key, i int);
    insert into t1 values(1, 1);
    insert into t11 values(2, 21);
    insert into t11 values(3, 31);
    commit;
    

    SESS2: insert into t1 values(2, 2);

    SESS1:

    MERGE INTO t1 d
    USING t11 s ON (d.pk = s.pk)
    WHEN NOT MATCHED THEN INSERT (d.pk, d.i) VALUES (s.pk, s.i);
    

    SESS2: commit;

    SESS1: ORA-00001