First turn off Auto-Commit in SQL Developer.
 
select * from coord
/
 
begin
   savepoint s1;
   insert into coord values (12, 16);
   insert into coord values (18, 34);
   rollback to s1;
end;
/
 
select * from coord
/
 
 
The table coord did not change!
 
Now we add an exception handler.
Note the division by 0!
 
 
begin
   insert into coord values (1000, 2000);
   insert into coord values (100/4, 60/0);
   exception
      when others then
         rollback;
end;
/
 
 
 
Due to the division by 0 the second insert throws an exception.
"others" is the universal exception. If anything goes wrong this exception
handler catches it.  The rollback effects BOTH INSERT STATEMENTS.
Even though I did not set a savepoint!
 
However, there exist man specialized conditions. A division by zero
 
exception handler is written like this:
 
 
begin
   insert into coord values (1000, 2000);
   insert into coord values (100/4, 60/0);
   exception
      when zero_divide then
         rollback;
         dbms_output.put_line('Division by zero attempted.');
end;
/
 
 
Here are especially interesting conditions that Oracle detects:
 
CURSOR_ALREADY_OPEN
INVALID_CURSOR
NO_DATA_FOUND
 
declare 
    av number; bv number; cv number;
begin
   select a into av from bar;
   -- insert into coord values(111, 222);
   dbms_output.put_line(av);
   
   exception
      when NO_DATA_FOUND then
      dbms_output.put_line('NO DATA FOUND!');
      rollback;
end;
/
 
 
 
====================================================
This is an additional exercise.  Not part of the exam material. 
 
How to insert date into several tables, when I have the
names of the tables in yet another table.
 

This program constructs new table names from a given table tablenames

and a prefix string (the letter ‘t’).

 

Then it inserts into that table of the constructed name.

But if the table of the constructed name does not exist, the loop continues after execution.

 

This is achieved by including a nested begin/end block in the middle of the FOR loop.

If something goes wrong with INSERT this begin/end has its own exception handler.

After the missing table exception was thrown, the loop continues to the next table name.

 

With a little tweak (doing tname.nam || ‘t’) and putting UCIDs of my students into tablenames I could insert into all of my students tables, IFF the students made those tables public for insert. 

 

The inserted value could also be changed to a simple integer counter.

 

 

declare
   one_name varchar2(4);
   comm varchar2(90);
begin
   for tname in (select * from tablenames)
   loop
      -- dbms_output.put_line(tname.nam);
      one_name := 't' || tname.nam;               -- construct table name
      dbms_output.put_line(one_name);
      comm :=  'insert into ' || one_name || ' values(' || tname.nam || ')';
      dbms_output.put_line(comm);
      begin
          execute immediate  'insert into ' || one_name || ' values(' || tname.nam || ')';
          exception
             when others then
                 dbms_output.put_line('No such table');
      end;
   end loop;
end;
/