Force Oracle Drop Global Temp Table Force Oracle Drop Global Temp Table oracle oracle

Force Oracle Drop Global Temp Table


Oracle global temporary tables are not transient objects. They are proper heap tables. We create them once and any session can use them to store data which is visible only to that session.

The temporary aspect is that the data is not persistent beyond one transaction or one session. The key implementation detail is that the data is written to a temporary tablespace not a permanent one. However, the data is still written to - and read from - disk, so there is a notable overhead to the use of global temporary tables.

The point is we are not supposed to drop and recreate temporary tables. If you're trying to port SQL Server style logic into Oracle then you should consider using PL/SQL collections to maintain temporary data in-memory. Find out more.

The specific cause of ORA-14452 is that we cannot drop a global temporary table which has session scope persistence if it has contained data during the session. Even if the table is currently empty...

SQL> create global temporary table gtt23 (col1 number)  2  on commit preserve rows  3  /Table created.SQL> insert into gtt23 values (1);1 row created.SQL> commit;Commit complete.SQL> delete from gtt23;1 row deleted.SQL> commit;Commit complete.SQL> drop table gtt23;drop table gtt23           *ERROR at line 1:ORA-14452: attempt to create, alter or drop an index on temporary table already in useSQL>

The solution is to end the session and re-connect, or (somewhat bizarrely) to truncate the table and then drop it.

SQL> truncate table gtt23;Table truncated.SQL> drop table gtt23;Table dropped.SQL> 

If some other session is using the global temporary table - and that is possible (hence the global nomenclature) then you won't be able to drop the table until all the sessions disconnect.

So the real solution is to learn to use global temporary tables properly: create specific global temporary tables to match each report. Or, as I say, use PL/SQL collections instead. Or, even, just learn to write well-tuned SQL. Often we use temporary tables as a workaround to a poorly-written query which could be saved with a better access path.


Having looked at your full code, the flow seems even more bizarre:

  1. Drop and re-create a global temporary table
  2. Populate temporary table
  3. Select from temporary table into PL/SQL array
  4. Insert into actual table using bulk insert from PL/SQL array

There's so much overhead and wasted activity in here. All you need to do is take the data you insert into v2d_temp and directly populate vertical_design, ideally with an INSERT INTO ... SELECT * FROM statement. You will require some pre-processing to convert a JSON array into a query but that is easy to achieve in either Java or PL/SQL.

It seems certain to me that global temporary tables are not the right solution for your scenario.


"our boss or other persons persist to do something through their way, so you cannot change that"

What you have is a Boss Problem not a Programming Problem. Consequently it is off-topic as far as StackOverflow goes. But here are some suggestions anyway.

The key thing to remember is that we are not talking about a compromise on some sub-optimal architecture: what your boss proposes clearly won't work in a multi-user environment. so, your options are:

  1. Ignore the ORA-14452 error, proceed into production and then use the "but you told me to" defence when it all goes horribly wrong. This is the weakest play.
  2. Covertly junk the global tables and implement something which will work in a multi-user scenario. This is high-risk because you have no defence if you botch the implementation.
  3. Speak to your boss. Tell them you're running into the ORA-14452 error, say you have done some investigation and it appears to a fundamental issue with using global temporary tables in this fashion but obviously you've overlooked something. Then, ask them how they got around this problem when they've implemented it before. This can go several ways, maybe they have a workaround, maybe they'll realise that this is the wrong way to use global temporary tables, maybe they'll tell you to get lost. Either way, this is the best approach: you've raised concerns to the appropriate level.

Good luck.


Another approach worth considering here is to rethink whether you need a temporary table at all.

It is a very common programming practice among those who transition from other RDBMSs to Oracle to overuse them, because they do not understand that you can use such features as Common Table Expressions to implicitly materialise a temporary result set that can be referenced in other parts of the same query, and on other systems it has become natural to write data to a table and then select from it.

The failure is usually compounded by not understanding that PL/SQL-based row by row processing is inferior in almost every respect to SQL-based set processing -- slower, more complex to code, more wordy, and more error prone -- but Oracle presents so many other powerful features for SQL processing that even when it is required it can generally be integrated directly into a SQL SELECT statement anyway.

As a side-note, in 20 years of writing Oracle code for reporting and ETL, I only needed to do use row-by-row processing once, and never needed to use a temporary table.


Killing sessions is the only way to work around ORA-14452 errors. Use the data dictionary to find other sessions using the temporary table and kill them with a statement like alter system kill session 'sid,seriall#,instance_id';.

This is the "official" solution mentioned in the Oracle support document HOW TO DIAGNOSE AN ORA-14452 DURING DROP OF TEMPORARY TABLE (Doc ID 800506.1). I've successfully used this method in the past, for a slightly different reason. Killing sessions requires elevated privileges and can be tricky; it may require killing, waiting, and trying again several times.

This solution is almost certainly a bad idea for many reasons. Before you implement this, you should try to leverage this information as proof that this is the wrong way to do it. For example, "Oracle documentation says this method requires alter system privilege, which is dangerous and raises some security issues...".