René Nyffenegger's collection of things on the web | |
René Nyffenegger on Oracle - Most wanted - Feedback
- Follow @renenyffenegger
|
December 19, 2005: On triggers, sequences, autonumbers and failing inserts | ||
Oracle's way to generate the SQLServer's equivalent of
autonumbers is to use
triggers and
sequences.
I am particularly interested in what happens when I create a sequence and a trigger, do some inserts of which one fails.
Will the sequence be increased or not? Here's the answer.
As usual for such cases, I start by creating a table:
create table autonumber_tbl ( autonumber number primary key, column_1 varchar2(10), column_2 varchar2(20) check (column_2 = upper(column_2)) );
There's a check check constraint on the table that allows uppercase words
in column_2 only.
Next: the sequence...
create sequence autonumber_seq;
... and the trigger.
create trigger autonumber_trg before insert on autonumber_tbl for each row begin select autonumber_seq.nextval into :new.autonumber from dual; end; /
Finally: a little autonomous block:
declare prevent_ora_08002 number; -- sequence AUTONUMBER_SEQ.CURRVAL is not yet defined in this session procedure fill( col_1 in varchar2, col_2 in varchar2 ) is returned_autonumber number; seq_value number; begin dbms_output.new_line; dbms_output.put_line('inserting: ' || col_1 || ' ' || col_2); select autonumber_seq.currval into seq_value from dual; dbms_output.put_line(' sequence before: ' || seq_value); begin insert into autonumber_tbl (column_1, column_2) values (col_1 , col_2 ) returning autonumber into returned_autonumber; exception when others then null; end; select autonumber_seq.currval into seq_value from dual; dbms_output.put_line(' sequence after: ' || seq_value); dbms_output.put_line(' returned autonumber: ' || returned_autonumber); end; begin -- prevent: sequence .... is not yet defined in this session select autonumber_seq.nextval into prevent_ora_08002 from dual; fill('foo', 'FOO'); fill('bar', 'BAR'); fill('BAZ', 'baz'); -- col_2's baz is in small caps, will fail fill('qux', 'QUX'); end; /
Executing this block gives:
inserting: foo FOO sequence before: 1 sequence after: 2 returned autonumber: 2 inserting: bar BAR sequence before: 2 sequence after: 3 returned autonumber: 3 inserting: BAZ baz sequence before: 3 sequence after: 4 returned autonumber: inserting: qux QUX sequence before: 4 sequence after: 5 returned autonumber: 5
As can be seen, the sequence is incremented even in the case where an insert fails.
More on OracleThis is an on Oracle article. The most current articles of this series can be found here.
|