It seems that the problem is when you are trying to update and delete the same record in the same time. It is a strange error message I admit. You asked where is non-deterministic Where-clause - there is no such clause and that is the problem. Lets say you have 3 records in your taable:
insert into t (id, val) values (1, 1);
insert into t (id, val) values (2, 2);
insert into t (id, val) values (3, 3);
commit;
--
-- ID VAL MODIFIED
-- 1 1 30-JUN-22 06.55.45.683595000
-- 2 2 30-JUN-22 06.55.45.690624000
-- 3 3 30-JUN-22 06.55.45.693622000
Now, your command is:
merge into t
using (
select 1 id, 10 val, 1 flag from dual
) s on (t.id = s.id)
when matched then
update set t.val=s.val
delete where s.flag=1
-- Result is SQL Error: ORA-30926
Update should be done on record with id=1 and delete should be done with s.flag=1 which means s.id=1 and therefore the record to delete is id=1. The same record.
Now lets see this:
merge into t
using (
select 1 id, 10 val, 1 flag from dual union all
select 2 id, 20 val, 2 flag from dual union all
select 3 id, 30 val, 3 flag from dual
) s on (t.id = s.id)
when matched then
update set t.val=s.val
delete where s.flag=1
-- Result is SQL Error: ORA-30926
... above is trying to do the same as in your question but on all three records
But if you change the where clause of delete statement and add the where clause to update statement to be deterministic there will be no error messages
merge into t
using (
select 1 id, 10 val, 1 flag from dual union all
select 2 id, 20 val, 2 flag from dual union all
select 3 id, 30 val, 3 flag from dual
) s on (t.id = s.id)
when matched then
update set t.val=s.val where s.flag = 1
delete where s.flag != 1
Finaly, lets go back to your command. There are some data from dual merged to the record with id=1. Update should be done over that record and delete command should have deterministic where clause that excludes deletion of the record that is being updated. That deterministic where clause shoud be like here:
merge into t
using (
select 1 id, 10 val, 1 flag from dual
) s on (t.id = s.id)
when matched then
update set t.val=s.val
delete where s.flag != 1
-- 1 rows merged
The problem disapears if you disable the before update trigger. If it is enabled then the trigger demands this determinism. And if you have an active after update trigger there is no problem because after update has been done there is no conflict and the record will be deleted.
CONCLUSION:
In this case when there is a table with BEFORE UPDATE trigger enabled when you try to update and delete the record simultaneously using merge there are two transactions that should be imposed. As the update transaction is interrupted by a db trigger changing the record data the second transaction (delete) gets the flag that the record that should be deleted is changed by another transaction and demands for determinism.
If before update trigger do something else (updating some other table or record) and not change the record itself then the command as it is does not raise the error.
You can try to change the trigger to update some value in any other table and run your command as it is ---> there will be no error.