В Ubuntu 16.04 по умолчанию версия PHP 7.0, если вы хотите использовать другую версию, вам необходимо установить пакет PHP в соответствии с версией PHP:
sudo apt-get install php7.2-curl
sudo apt-get install php7.1-curl
sudo apt-get install php7.0-curl
sudo apt-get install php5.6-curl
sudo apt-get install php5.5-curl
Вызов называется MERGE. Посмотрите, я слишком ленив.
Остерегайтесь, однако, что MERGE не является атомарным, что может вызвать следующий эффект (спасибо, 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
DECLARE
tmp NUMBER(3,1);
BEGIN
SELECT COUNT(content_id) INTO tmp FROM contents WHERE (condition);
if tmp != 0 then
INSERT INTO contents VALUES (...);
else
INSERT INTO contents VALUES (...);
end if;
END;
Я использовал приведенный выше код. Это длинный, но простой и сработавший для меня. Аналогично, с кодом Мишеля.
Это только вставляет, если элемент, который нужно вставить, еще не присутствует.
Работает так же, как:
if not exists (...) insert ...
в T-SQL
insert into destination (DESTINATIONABBREV)
select 'xyz' from dual
left outer join destination d on d.destinationabbrev = 'xyz'
where d.destinationid is null;
может быть не очень красивым, но это удобно:)
insert into destination select 'id', 'xyz' from dual where not exists (select id from destination where id = 'id')
– robinst
14 June 2012 в 15:32
code
, если не существует (...) insert ... code
Ошибка (22,16): PLS-00204: функция или псевдо-столбец «EXISTS» могут использоваться только внутри оператора SQL
– Maxple
31 January 2018 в 15:39
Это ответ на комментарий, отправленный erikkallen:
Вам не нужна временная таблица. Если у вас есть только несколько строк, (SELECT 1 FROM dual UNION SELECT 2 FROM dual). Почему ваш пример даст ORA-0001? Не объединил бы блокировку обновления на ключе индекса и не продолжил бы до тех пор, пока Sess1 не вернется или не вернется? - erikkallen
blockquote>Ну, попробуйте сами и скажите, есть ли у вас такая же ошибка:
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
Этот код находится на клиенте, тогда у вас много поездок на сервер, чтобы устранить это.
Вставьте все данные во временную таблицу, скажем, T с той же структурой, что и myFoo
Тогда
insert myFoo
select *
from t
where t.primary_key not in ( select primary_key from myFoo)
Это должно работать и с другими базами данных - я сделал это на Sybase
. Не самое лучшее, если очень мало новых данных для если вы скопировали все данные по проводу.
Поздняя вечеринка, но ...
С помощью oracle 11.2.0.1 есть семантический намек , который может это сделать: IGNORE_ROW_ON_DUPKEY_INDEX
Пример:
insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(customer_orders,pk_customer_orders) */
into customer_orders
(order_id, customer, product)
values ( 1234, 9876, 'K598')
;
UPDATE: Хотя этот подсказку работает (если вы правильно произносите его), существуют лучшие подходы , которые не требуют Oracle 11R2:
Первый подход: прямой перевод вышеизложенного семантического намека:
begin
insert into customer_orders
(order_id, customer, product)
values ( 1234, 9876, 'K698')
;
commit;
exception
when DUP_VAL_ON_INDEX
then ROLLBACK;
end;
Второй aproach & mdash; lot быстрее, чем оба вышеупомянутых намека, когда есть много разногласий:
begin
select count (*)
into l_is_matching_row
from customer_orders
where order_id = 1234
;
if (l_is_matching_row = 0)
then
insert into customer_orders
(order_id, customer, product)
values ( 1234, 9876, 'K698')
;
commit;
end if;
exception
when DUP_VAL_ON_INDEX
then ROLLBACK;
end;
Если вы НЕ хотите сливаться с другой таблицей, а скорее вставляете новые данные ... Я придумал это. Возможно, лучший способ сделать это?
MERGE INTO TABLE1 a
USING DUAL
ON (a.C1_pk= 6)
WHEN NOT MATCHED THEN
INSERT(C1_pk, C2,C3,C4)
VALUES (6, 1,0,1);
Мы можем объединить DUAL и NOT EXISTS для архивирования вашего требования:
INSERT INTO schema.myFoo (
primary_key, value1, value2
)
SELECT
'bar', 'baz', 'bat'
FROM DUAL
WHERE NOT EXISTS (
SELECT 1
FROM schema.myFoo
WHERE primary_key = 'bar'
);
INSERT INTO schema.myFoo ( primary_key , value1 , value2 ) SELECT 'bar1' AS primary_key ,'baz1' AS value1 ,'bat1' AS value2 FROM DUAL WHERE (SELECT 1 AS value FROM schema.myFoo WHERE LOWER(primary_key) ='bar1' AND ROWNUM=1) is null;
Если ваша таблица является «независимой» от других (я имею в виду, что она не будет вызывать каскадное удаление или не установит отношения внешних ключей к нулю), хороший трюк может состоять в том, чтобы сначала УДАЛИТЬ строку, а затем снова ВСТАВИТЬ , Это может выглядеть так:
УДАЛИТЬ ОТ MyTable WHERE prop1 = 'aaa'; // предполагая, что он выберет не более одной строки!
INSERT INTO MyTable (prop1, ...) VALUES ('aaa', ...);
Если вы удаляете то, что не существует, ничего не произойдет.