Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question.

Asked: October 10, 2007 - 9:52 pm UTC

Last updated: October 15, 2007 - 11:33 am UTC

Version: 10.2.0.3

Viewed 1000+ times

You Asked

Hello,Tom!
I am very lucky to get this chance.I have 2 quesitons:
1:If a table have a fk,when I do insert /*+ append */ into tname select ...,oracle will ignore the hint ,yes?
2:I know ,a select will not hold a lock a the table,so I want to know ,when a select is onging,before it finished,we drop or truncate the table ,what will happen,so I did these cases below:
DB: 10.2.0.3 EE
case 1:drop table before select finished.
case 2: drop table purge before select finished
case 3: truncage table before select finished.

--Here are cases:
SQL> create table t1(id int);
Table created.
SQL> insert into t1 select object_id from all_objects;
50021 rows created.
SQL> commit;

case 1:
--session 1:
    declare cursor c is select id from t1;
    v int;
    con  int;
    begin
    con:=1;
   open c;
   dbms_lock.sleep(30); 
   loop
   con:=con+1;
   fetch c into v;
   exit when c%notfound;
   end loop;
  dbms_output.put_line(to_char(sysdate,'HH24:MI:SS')|| ' rows fetched: '||con);
  end;
/
20:11:57SQL>  rows fetched: 50023  <<all rows fetched
PL/SQL procedure successfully completed.
--session 2
20:11:20SQL> drop table t1;

case 2:
--session 1
20:14:10 SQL> /
20:14:40SQL> rows fetched:  3302  <<only fetchs 3302 rows and no error.
PL/SQL procedure successfully completed.
--session 2
20:14:20SQL> drop table t1 purge;

case 3
--session 1
20:16:39 SQL> /
    declare cursor c is select id from t1;
*
ERROR at line 1:
ORA-08103: object no longer exists <<error 8103 rised
ORA-06512: at line 12  

--session 2
20:16:50 SQL>truncate table t1;

I noticed:
--when I do drop ,select will fetch all rows even the table was drop before the fetch started.
--when I do drop ... purge,select will only fetch fetch 3302 rows .
and 1 and 2 didn't return a ORA-08103 error;
--when I do truncate table, the fetch result with error ora-08103.
Could you tell me what exactly oracle does in these cases?Why case 2 ,fetch only get 3302 rows,but does not rise ora-08103?

and Tom said...

1) correct, the foreign key will prevent the direct path insert, it will be a conventional path insert, you can observe this easily:

ops$tkyte%ORA10GR2> create table p ( x int primary key );
Table created.

ops$tkyte%ORA10GR2> create table c1 ( x references p );
Table created.

ops$tkyte%ORA10GR2> create table c2 ( x int );
Table created.

ops$tkyte%ORA10GR2> insert into p select rownum from all_users;
57 rows created.

ops$tkyte%ORA10GR2> commit;
Commit complete.

ops$tkyte%ORA10GR2> insert /*+ append */ into c1 select * from p;
57 rows created.

ops$tkyte%ORA10GR2> insert /*+ append */ into c2 select * from p;
57 rows created.

ops$tkyte%ORA10GR2> select count(*) from c1;

  COUNT(*)
----------
        57

<b>the fact we read that that implies it was not direct pathed - because if it was, we would get:</b>

ops$tkyte%ORA10GR2> select count(*) from c2;
select count(*) from c2
                     *
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel

<b>that error, until we commit the modification:</b>

ops$tkyte%ORA10GR2> commit;
Commit complete.

ops$tkyte%ORA10GR2> select count(*) from c2;

  COUNT(*)
----------
        57



2) the answer is "it depends"

If you drop/truncate the table after opening the cursor, but before you fetch - you will likely get the 8103.

If you do not get the 8103 error, it is likely you will fetch the data, unless something comes along and reuses the space (as you emulated).

Since we do not do DDL in a production system :) this is a purely academic question of course.

Rating

  (6 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

About dropping or truncating during select

Michel Cadot, October 11, 2007 - 8:25 am UTC


Have a look at the following thread (Does a select statment hold a lock on the table?) starting from, I think, the same poster:

http://www.orafaq.com/forum/t/90714/102589/

Regards
Michel

drop purge and truncate

alan tan, October 11, 2007 - 10:33 am UTC

Hi,Tom:
I think drop table ...purge will release space as well as truncate table does.
But here,you see:
The process run successfully without 8103 error even it just fetched a few rows when I do drop table ..purge.
But we got 8103 when we truncate the table ?
why?
Regards!
Alan
Tom Kyte
October 14, 2007 - 9:48 pm UTC

if you flip a coin once and it comes up heads - what does that show?
if you flip it 100 times and it comes up heads - what does that show?

does it show that coins always come up heads? No, it shows that a coin could come up heads, you just demonstrated it. It doesn't make it so that it has to be heads in all cases.

drop table t purge is not the same as truncate.

the purge just allows for the space to be immediately reused, it is not in the recycle bin

truncate changes the tables data object id, points it to new space, changes the TABLE entirely.

they are different commands.

C1 table

A reader, October 12, 2007 - 9:42 am UTC

If C1 is compressed does that mean we can't insert compressed data into that table because of the FK? We can't do direct path so no compression, right?

Regarding the delete new question policy, will you take more new questions from now on (new threads)?
Tom Kyte
October 14, 2007 - 9:10 pm UTC

I will not take new questions on an existing thread, only address things that relate to the question already there.

So I can take more new questions. I'm aiming for 10 new questions on most days.


You can direct path if you disable then enable the key.

You can load and then alter table Child MOVE; - that'll direct path it as well.

Thanks,Tom!

A reader, October 14, 2007 - 11:24 pm UTC

Hi,Tom:
thanks for your replay!
I think this would be an Oracle bug when we get an incorrect result but successfully ,it should raise a 8103 error every time the the result is not corret,yes?

<<You said:truncate changes the tables data object id, points it to new space, changes the TABLE entirely.
What the meaning of tables data object id?does it mean the object id of table?
Regards!
Alan
Tom Kyte
October 15, 2007 - 11:33 am UTC

there is an object id, the primary key into obj$ to find the metadata about the table.

there is the data_object_id which starts life as the same as the object id but changes every time you truncate... it points to the actual data segment.

object id vs data object id

Michel Cadot, October 15, 2007 - 2:59 am UTC


Object id is defined as object creation time, the object then has a data object id equals to the object id.
This data object id is something like an object instantiation id. When you truncate a table, it keeps its object id but data object id changes.
The reason is clear: it prevents from using old ROWID from a previous "table instantiation".
ROWID contains data object id, when you try to use a rowid then this data object id is compared to the one recorded in block header. If they don't match then you're trying to use an old and no more valid rowid and an error is returned.

Regards
Michel

Thanks Tom! Thanks Michel!,I think I am clear now:)

A reader, October 15, 2007 - 11:17 pm UTC


More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library