Whenever I run a sql script using Sql*plus and check for $?, I get 0 even when the script wasn\'t succesful.
Example
#$ sqlplus user/password@instanc
Vlad's is the answer I'd use. To augment his, however, I try to use an explicit EXIT statement if I really need that return status. For example
column status_for_exit new_value exitcode noprint select status_computation (parm, parm) as status_for_exit from dual; exit &exitcode;