You are on page 1of 3

Creating BETTER auto-increment columns in Oracle I was explaining to a developer today how Oracle doesn t support auto

-increment co lumns for IDs and how you have to implement your own. I wanted to point him to a tutorial but I found that most of the tutorials have PL/SQL code with unexplain ed side effects. So I thought I d post some Oracle PL/SQL code that behaves just l ike a MySQL or PostgreSQL auto-increment column, but which also fixes the sequen ce number when an application provides its own ID number for a record, which is one place where MySQL and PostgreSQL autoincrement columns fail. Step 1: Know the names of your tablespaces. Know which tablespace you want to us e for your tables and which tablespace you want to use for your indexes. Don t ass ume that Oracle is going to put the table in the right place. To get a list of a vailable tablespaces: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< create table OPERATORE ( id number not null, cognome€ varchar2(100),€ nome€ varchar2(100), constraint operatore_pk primary key(id) using index tablespace INDX ) tablespace TDATA; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Step 1: Know the names of your tablespaces. Know which tablespace you want to us e for your tables and which tablespace you want to use for your indexes. Don t ass ume that Oracle is going to put the table in the right place. To get a list of a vailable tablespaces:

select tablespace_name from user_tablespaces; Step 2: Create your table. In this example the table is built in the tablespace TDATA and the primary key index is built in the tablespace INDX. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< create table example ( id number not null, name varchar2(30), constraint example_pk primary key(id) using index tablespace INDX ) tablespace TDATA; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Note that by declaring the id column not null you can t add a record with an empty I D field, ever. Creating the primary key constraint on a separate line allows us to name the con straint, which can be handy when you re looking through the data dictionary later on trying to figure out which constraint does what.

Step 3: Create a sequence. In this case I create an ID sequence that starts at 1 and goes on from there. If you want to start your ID sequence with a different number, or increment by some other amount, change these values.

end loop.0).id is null then -. For example: SQL> insert into example (id. get one from the sequence select example_id_seq. here are two: Method 1: Use a sequence-generated ID for all IDs. else -. while cur_seq < max_id loop select example_id_seq. SQL> insert into example (name) values ('Frankenstein'). / <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Method 1 will always use a sequence-generated ID no matter what. 1 row created.<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< create sequence example_id_seq start with 1 increment by 1. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Step 4: Create a trigger.nextval into :new. 1 row created. name) values (100. 1 row created. so update the sequence select greatest(nvl(max(id).No ID passed. :new. end. This is what does the actual work setting the ID numbe r.nextval into :new.-----------------------------1 Earl 2 Cleopatra 3 Frankenstein In this case the trigger-supplied ID 1 overwrote the user-supplied id 100. Method 2: Allow users to supply their own IDs when they want to. . cur_seq number. 'Earl'). ID NAME ---------.id from dual.id) into max_id from example.nextval into cur_seq from dual.nextval into cur_seq from dual. create or replace trigger example_insert before insert on example for each row declare max_id number. SQL> select * from example.id from dual. end if. create or replace trigger example_insert before insert on example for each row <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< begin select example_id_seq.ID was set via insert. begin if :new. SQL> insert into example (name) values ('Cleopatra'). select example_id_seq. There are many ways to do this.

It also updates the sequence so t hat the next value of the sequence won t collide with IDs supplied by an insert st atement. which is what MySQL and PostgreSQL do. / <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Method 2 will use the sequence-generated ID if the insert statement doesn t supply an ID. 'Frankenstein'). including old ID numbers. . 'Cleopatra'). PRIMARY KEY (ID) ). Name VARCHAR(40) NOT NULL. SQL> delete from example. name) values (200. SQL> insert into example (id. 1 row created. let s say I m using Trigger Method 2 and just loaded the table with a b unch of old data. SQL> select * from example. For example. CREATE TABLE Product ( ID SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT. 1 row created. 1 row created. 3 rows deleted. ID ---------200 300 301 NAME -----------------------------Cleopatra Frankenstein Earl <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Drop table Product. SQL> insert into example (name) values ('Earl'). SQL> insert into example (id. name) values (300.end.