I don't have anything new to offer but maybe a different perspective could help? My takeaway from previous comments is that the result of
if (id > 0)
is irrelevant. Troubleshooting the IF condition and what will happen during execution time is missing the real issue. The example could be reduced even further:
BEGIN
IF (0 > 0) THEN
UPDATE EMPLOYEE_DETAILS set ALT_ID = 1234 WHERE EMP_ID = '3456';
END IF;
END;
/
Now we have a block of code that does nothing because we know the IF condition will never be true.
You'll still see the error. Not because the IF condition isn't working as you expect. Not because the UPDATE statement fails when executed, it is never executed. You get the error because the UPDATE statement fails to compile. No matter how many safety checks you wrap around it, it will still be compiled. So the problem lies in all the things the compiler is trying to do behind the scenes.
That is:
-Verify references to valid database objects
-Verify necessary privileges are in place to access those objects
-Create schema object dependencies
etc...
That's the difference when you make the UPDATE statement dynamic. Dynamic SQL forgoes the benefits of static, compiled, statements.