Это довольно распространенная модель. В зависимости от того, какую версию Oracle вы используете, вы можете использовать оператор слияния (я не уверен, в какой версии он появился).
create table test_merge (id integer, c2 varchar2(255));
create unique index test_merge_idx1 on test_merge(id);
merge into test_merge t
using (select 1 id, 'foobar' c2 from dual) s
on (t.id = s.id)
when matched then update set c2 = s.c2
when not matched then insert (id, c2)
values (s.id, s.c2);
Слияние предназначено для объединения данных из исходной таблицы, но вы можете подделать их для отдельных строк, выбрав данные из двойного.
Если вы не можете использовать слияние, оптимизируйте его для наиболее распространенного случая. Будет ли процесс, как правило, не находит запись и должен вставить ее, или ему обычно нужно обновить существующую запись?
Если вставка будет наиболее распространенной, лучше всего использовать следующий код:
begin
insert into t (columns)
values ()
exception
when dup_val_on_index then
update t set cols = values
end;
Если обновление является наиболее распространенным, измените порядок действий:
begin
update t set cols = values;
if sql%rowcount = 0 then
-- nothing was updated, so the record doesn't exist, insert it.
insert into t (columns)
values ();
end if;
end;
Вы не должны выдавать команду select для проверки строки и принятия решения на основе результата - это означает, что вам всегда нужно будет запускать два оператора SQL, когда вы можете использовать один из них большую часть времени (или всегда, если вы используете слияние). Чем меньше операторов SQL вы используете, тем лучше будет работать ваш код.