Best approach:
* Upgrade to 12c or higher
* Set the column to have a sequence default or be an identity
* Use the returning clause to get the value:
create sequence s;
create table t (
c1 int,
c2 int
default s.nextval
);
var v number;
insert into t values ( 1, default )
returning c2 into :v;
print :v
V
----------
1
Note this only works with insert ... values. Insert ... select doesn't support the returning clause.
Until you upgrade whether you use a trigger or manually assign the sequence is kinda up to you.
Personally I think it's better to use the sequence in your insert and return the value like this:
insert into t values ( 999, s.nextval )
returning c2 into :v;
print :v
V
----------
2
This is clearer what you intend and avoids trigger overheads. But you may need the trigger to cover for cases where the sequence value isn't supplied.
If this could be a concern for you, you can define the trigger to only fire when c2 is null:
drop table t
cascade constraints purge;
create table t (
c1 int,
c2 int
);
create or replace trigger trig
before insert on t
for each row
when ( new.c2 is null )
begin
dbms_output.put_line ( 'Fired!' );
:new.c2 := s.nextval;
end;
/
insert into t values ( 100, s.nextval )
returning c2 into :v;
print :v
V
----------
3
insert into t ( c1 ) values ( 101 )
returning c2 into :v;
Fired!
print :v
V
----------
4