How to check parameter value existence in a procedure?
If you use a count() aggregate on a resultset that has no rows, you'll get zero, not a null.

If a SELECT doesn't find anything, an exception is raised (NO_DATA_FOUND), and you need to catch that exception in an EXCEPTIONS block.

exceptions
  when no_data_found:
    dbms_output.put_line('ooups');
end;


In your case the second select is raising the exception - since zero is not null, your first if branch will not be taken. (update doesn't raise an exception if it doesn't update anything.)

Your procedure is generally too complicate already though. You can declare variables in the procedure "header" directly, remove both selects - all the info you want can be gotten from a single update.

create or replace
procedure cust_pay(temp_code number, pay_amount number)
as
  new_balance number;
begin
  update customer
  set cbalance = cbalance - pay_amount
  where cust_code = temp_code
  returning cbalance into new_balance;

  if sql%rowcount = 0 then
    dbms_output.put_line('No such customer: ' || temp_code);
  elsif new_balance &lt; 0 then
    dbms_output.put_line('Negative: ' || new_balance);
  else
    dbms_output.put_line('Positive: ' || new_balance);
  end if;
end;


(This assumes that cust_code is unique.)

If the update didn't do anything, sql%rowcount will be zero, which tells you whether that customer exists or not (equivalent to your first select).
The update itself is unchanged from your code except that the returning ... into avoids the need for your third select and grabs the updated value directly into a local variable.