I tried the following code different ways, like by taking out the while or the if, but when I put both together (if and while), I always get the error at the end...
CHAR is a fixed-length data type that uses as much space as possible. So a:= a||'one '; will require more space than is available. Your problem can be reduced to the following example:
declare
v_foo char(50);
begin
v_foo := 'A';
dbms_output.put_line('length of v_foo(A) = ' || length(v_foo));
-- next line will raise:
-- ORA-06502: PL/SQL: numeric or value error: character string buffer too small
v_foo := v_foo || 'B';
dbms_output.put_line('length of v_foo(AB) = ' || length(v_foo));
end;
/
Never use char. For rationale check the following question (read also the links):