Click here to Skip to main content
15,888,579 members
Articles / Database Development / SQL Server
Technical Blog

Oracle Sequence Promotes Poorly Maintainable Code

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
4 Apr 2013CPOL3 min read 9.9K   2   10
Oracle tables have no built-in mechanism for auto numbering. Instead, you must create a separate unique Sequence object and use it each time a record is inserted into the database.

I started my professional career working with Microsoft's SQL Server. I spent twelve years off and on learning how to design a database and write stored procedures in T-SQL. Then this last October, I switched jobs and was exposed to a new database platform, Oracle. Since this switch, I have used every curse word I know and invented new ones to express my frustration at interacting with an Oracle 10x something database. I'll leave the rest of my ranting for another post and just focus on one aspect of Oracle that has frustrated me recently.

I started creating my first new table in Oracle and started defining the columns. I always start with an ID column that is typically used as primary key of the table. As I went to select the column type, I didn't see anything labeled "autonumber". Trying again, I looked for integer, but that isn't there either. Oracle only supports the "Number" column. There, you can provide the precision before and after the decimal point. After selecting the number column, I looked all over for something that would mark the column as unique and set for an autonumber sequence. Striking out  quickly, it was time to ask Google and start learning about Sequence objects.

Oracle tables have no built-in mechanism for auto numbering. Instead, you must create a separate unique Sequence object and use it each time a record is inserted into the database.

SQL
CREATE SEQUENCE customers_seq  START WITH     1000  INCREMENT BY   1  NOCACHE  NOCYCLE;

Then each time the sequence is used, it looks something like

SQL
INSERT INTO customers (ID, Name...) VALUES (customers_seq.nextval, 'Hogan Haake'...);

Comparing this to the SQL Server I'm used to, if a column is autonumbered, you just exclude it in the insert and it automatically gets the next ID on insert.

SQL
INSERT INTO customers(Name, ...) VALUES ('Hogan Haake'...)

At this point, Oracle people could argue that I'm just lazy, or I just need to learn a new way. They are right on both accounts, but there is more to the story! I recently came across some bad code in part of my application where the developer didn't use the sequence.nextvalue for an insert, instead converting the current date into a number [YYMMDD Format] and inserted that into the table as a unique value. While that method worked, the unique number they were generating was quite far away from the current sequence. The system has been in production for two years now and the sequence number is about 6 months away from a "collision" with incorrectly inserted manual numbers in the ID column.

Current Sequence Value      Manual Sequence Value
107,000                     120,210     (first inserted 2012-Feb-10th)

The current sequence value is fast approaching the first manual sequence value. It was fortunate that the bug was found before it caused corrupt data and long nights for me. Due to the complexity of the system and time constraints, the simple fix of  incrementing the next value of the sequence to 500,000 to avoid any future collisions with "unique" numbers was chosen. It would be nice to fix the offending code with the correct sequence number, but management decided the code worked enough that we could move on to other problems.

In a SQL Server environment, if you try to insert a value into an autonumber field, an error is produced preventing this type of error from happening.

I'm not sure what other issues I'm going to encounter with this new environment, but I sure miss SQL Server. If you still don't think SQL Server is better, consider community support. Who would you rather trust for help?

Pinal Dave (SQL Server) or Don Burleson (Oracle)?

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
United States United States
I'm a nice guy Smile | :)

Comments and Discussions

 
QuestionSurrogate Keys Pin
Jasmine25018-Apr-13 10:00
Jasmine25018-Apr-13 10:00 
AnswerRe: Surrogate Keys Pin
snorkie8-Apr-13 11:41
professionalsnorkie8-Apr-13 11:41 
GeneralRe: Surrogate Keys Pin
Jasmine25018-Apr-13 13:12
Jasmine25018-Apr-13 13:12 
Properly defining your primary key eliminates that problem. You should never create an ID column, if a natural primary key exists. Here's an example for a pizza company... I used to work this system, and we had a rule "One address per phone number" making phone number a natural primary key for their system (they are always USA numbers because it needs to be one we can call back). If you did this...

create table (
phoneNumber varchar(10) primary key,
name varchar(100),
address1 varchar(100),
...etc...
)

You won't have any of the problems you describe. In fact, in this situation, assigning a surrogate as the primary key ALLOWS corruption of the data because now you need an additional check to make sure phone numbers are unique. A surrogate key in this case does nothing but increase application complexity, increase storage space, and provide for a method of corrupting the data.

I have done my share of de-duping databases, and in all cases, the duplicates exist because the database was designed incorrectly, and in some cases, the use of a surrogate key was the design flaw. In one specific case it was "well, if we define our keys, it causes errors in the client app" - well I should hope so!

So, just as you should never salt your food before tasting it, you should not create identity columns when they are not needed.

We aren't going to finish this argument here though - Google for surrogate keys if you want - it's one of the database religious wars, along with plural/singular table names, use of triggers, usefulness of the normal forms, etc, etc...

I just wanted to bring it up because I see that Microsoft has taught you a bad habit, and rather than always doing it, you should think about whether it's appropriate or not. I've made some good money over the years fixing things that started with application of habits in inappropriate places - but that is money the companies didn't have to spend if the developers would have thought about their task. In programming, any time you start a sentence with "I always..." you are about to say something wrong.
GeneralRe: Surrogate Keys Pin
snorkie9-Apr-13 3:03
professionalsnorkie9-Apr-13 3:03 
GeneralRe: Surrogate Keys Pin
Jasmine25019-Apr-13 6:09
Jasmine25019-Apr-13 6:09 
QuestionUse Trigger Pin
Klaus Luedenscheidt4-Apr-13 19:43
Klaus Luedenscheidt4-Apr-13 19:43 
AnswerRe: Use Trigger Pin
snorkie5-Apr-13 6:04
professionalsnorkie5-Apr-13 6:04 
GeneralRe: Use Trigger Pin
Klaus Luedenscheidt5-Apr-13 17:48
Klaus Luedenscheidt5-Apr-13 17:48 
QuestionQuestion Pin
Wendelius4-Apr-13 6:53
mentorWendelius4-Apr-13 6:53 
GeneralRe: Question Pin
snorkie4-Apr-13 7:19
professionalsnorkie4-Apr-13 7:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.