Как выполнить вставку по условию? Ошибка: ORA-00928: missing SELECT keyword

Нашёл здесь, что синтаксис выглядит следующим образом: (прим.ред. источник больше не доступен)

INSERT
WHEN ([Condition]) THEN
INTO [TableName] ([ColumnName])
VALUES ([VALUES])
ELSE
INTO [TableName] ([ColumnName])
VALUES ([VALUES])
SELECT [ColumnName] FROM [TableName];

Но использовать значения из другой таблицы не требуется, а надо просто ввести новые заначения, поэтому делаю так:

INSERT 
WHEN EXISTS (SELECT 1 FROM FOO WHERE NAME = 'JOE') 
THEN
INTO BAR (NAME, AGE) 
VALUES ('JOE', 50)

но это приводит к исключению:

ORA-00928: missing SELECT keyword.

Как выполнить вставку с новыми значениями, если заданное значение найдено в другой таблице?


Свободный перевод вопроса How to insert conditionally? от участника @Kamil


Ответы (1 шт):

Автор решения: 0xdb

Причина ошибки в том, что вставка по условию см. conditional_insert_clause является частью мульти-табличной вставки см. multi_table_insert. Последняя синтаксически требует в конце обязательный подзапрос. Неважно, будут ли значения, полученные из этого подзапроса, использованы для вставки или нет. Так же неважно, что вставка производится только в одну таблицу. Важно однако, сколько строк вернёт подзапрос.

То есть для одиночной вставки подзапрос должен вернуть ровно одну строку:

create table t1 (id, val) as
    select 1, 10 from dual;

create table t2 (id, val) as
    select 2, 20 from dual;

insert
when exists (select 1 from t2 where val = 20) 
then into t1 (id, val) values (3, 30)
select null from dual;

1 row inserted.

Если таблица для вставки одна, то проще:

insert into t1 (id, val) 
select 4, 40 from t2 where val = 20 fetch first 1 row only;

1 row inserted.

select * from t1;

         ID         VAL
----------- -----------
          1          10
          3          30
          4          40
→ Ссылка