Помещение столбца в какое-либо выражение и переименование, похоже, работает. В приведенном ниже примере ISDELETED_
и ISDELETED
фактически одно и то же:
merge into (
select nvl(ISDELETED, ISDELETED) as ISDELETED_, ISDELETED, ID,
from ET.PSEUDODELETETABLE
) TARGET
using (select 1 as ID, 'Horst' as NAME from sys.dual) SOURCE
on (TARGET.ISDELETED_ = 1 and SOURCE.ID = TARGET.ID) -- Use the renamed version here
when matched then
update set ISDELETED = 0, NAME = SOURCE.NAME -- Use the original version here
when not matched then
insert values (SOURCE.ID, SOURCE.NAME, 0);
Примечание:
- Просто переименование не работает. Парсер кажется достаточно «умным», чтобы обнаружить, что это все тот же столбец. Но переименование и выражение в «глупом» выражении превосходит синтаксический анализатор.
- Это, очевидно, обходится дорого. Индексы не могут быть легко использованы в переименованном столбце, проверьте план выполнения. В этом конкретном примере это может работать
- Oracle может «исправить» это в будущем (и сделать обнаружение ORA-38104 более последовательным), поэтому этот обходной путь может прекратиться.
Кажется, это также работает, но определенно не позволяет разумно использовать индексы (проверьте еще раз свою версию Oracle):
merge into ET.PSEUDODELETETABLE TARGET
using (select 1 as ID, 'Horst' as NAME from sys.dual) SOURCE
on ((select TARGET.ISDELETED from dual) = 1 and SOURCE.ID = TARGET.ID)
when matched then
update set ISDELETED = 0, NAME = SOURCE.NAME
when not matched then
insert values (SOURCE.ID, SOURCE.NAME, 0);
Даже это работает (что вызывает серьезные сомнения относительно проверки ORA-38104 в целом)!
merge into ET.PSEUDODELETETABLE TARGET
using (select 1 as ID, 'Horst' as NAME from sys.dual) SOURCE
on ((TARGET.ISDELETED, 'dummy') = ((1, 'dummy')) and SOURCE.ID = TARGET.ID)
when matched then
update set ISDELETED = 0, NAME = SOURCE.NAME
when not matched then
insert values (SOURCE.ID, SOURCE.NAME, 0);
Я уже писал об этих обходных путях (и планах выполнения) здесь .