Мне на самом деле нравится первый потому что, когда существует много переменных, смешиваемых с текстом, который кажется легче прочитать в меня. Плюс, легче иметь дело с кавычками при использовании строки. Формат (), мм, формат. Вот достойный анализ из конкатенации строк.
Оператор называется MERGE. Посмотри, я слишком ленив.
Однако учтите, что MERGE не является атомарным, что может вызвать следующий эффект (спасибо, Мариус):
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: вставить в 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
Если этот код находится на клиенте, тогда у вас будет много обращений к серверу, чтобы это исключить.
Вставьте все данные в временную таблицу, скажем, T с той же структурой, что и myFoo
Затем
insert myFoo
select *
from t
where t.primary_key not in ( select primary_key from myFoo)
Это должно работать и с другими базами данных - я сделал это на Sybase
. Не лучше, если нужно вставить очень мало новых данных, поскольку вы скопировали все данные по сети. .
Это ответ на комментарий, отправленный erikkallen:
Вам не нужна временная таблица. если ты всего несколько строк (ВЫБЕРИТЕ 1 ИЗ dual UNION SELECT 2 FROM dual) будет делать. Почему ваш пример дал ORA-0001? Не слилось бы блокировку обновления ключа индекса, а не продолжайте, пока Sess1 не совершил или откатился? - erikkallen
Что ж, попробуйте сами и скажите, получите ли вы ту же ошибку или нет:
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: вставить в значения t1 (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