tags:

views:

79

answers:

2

I am trying to insert 1 to 10 numbers except 6and 8 in table messages,but when i fetch it from table mesages1, output is coming in this order 4 5 7 9 10 1 2 3 It should be like this 1 2 3 4 5 7 9 10 According to the logic ,it works fine when i omit commit or put it some where else, Please explain why it is happening? this is my code.

BEGIN
    FOR i IN 1..10
    LOOP
    IF i<>6 AND i<>8
    THEN
    INSERT INTO messages1
    VALUES (i);
    END IF;
    commit;
    END LOOP;
END;

select * from messages1;

+8  A: 

If you don't use ORDER BY, you should assume the order the results appear in is undefined. Often the results are in the same order they were inserted in, but it's not guaranteed.

Bottom line, if you want your results in some specific order, use ORDER BY.

Matti Virkkunen
This is happening in case of commit only ,if i insert values and commit in the last.The order remains the same.
Vineet
I already told you the order is undefined if you're not using ORDER BY. Are you looking for a detailed explanation about the internals of Oracle and why it sometimes returns results in some order and sometimes in another?
Matti Virkkunen
ya Matti ,could you please send me any link explaining the internals of it!!
Vineet
Sorry, never used Oracle. I'd have to Google that...
Matti Virkkunen
Escpecially update's can cause the movement of rows to other places but there can be a lot of order reasons too. You should never make your code depend on the order of inserts.
TTT
"order reasons" should be "other reasons"
TTT
A: 

As Matti says you need the order by clause explicity to guarantee the ordering is returned correctly.

When you have pending changes (ie uncommitted ones) you are the only one able to see them (generally...) this because they haven't been added to the data store where the other data is. Oracle maintains a separate list of pending changes which it uses to alter the results it it gets from the main data store. In your example the changing from this list happens to be returning in order, as there is very little data in the example Oracle presumably isn't needing to split the pending data in any way for optimise its storage.

Once the data is committed it will go into the main database storage and be ordered in any number of possible ways depending on how the table and partition is set up.

So in short, the data is coming from two different places before and after the commit, it just so happens they are returning in different orderings, but don't rely on them not always behaving like that.

Chris
To be more accurate, it's somewhat the reverse of what you've said here. Oracle doesn't maintain any "pending changes" list. It maintains a redo log, as well as undo blocks for each block change. The new and changed data blocks get stored, and it's when the data is queried that Oracle determines that the data hasn't been committed, and applies undo records to recreate the block as it appeared when the query started.So, the effect is the same, but the mechanism is different to what's been described here.
Jeffrey Kemp