Force Oracle Drop Global Temp Table

前端 未结 4 1226
死守一世寂寞
死守一世寂寞 2020-12-10 06:08

In our project I create some global temp table that will be like these:

CREATE GLOBAL TEMPORARY TABLE v2dtemp (
  id           NUMBER,
  GOOD_TYPE_GROUP              


        
4条回答
  •  攒了一身酷
    2020-12-10 06:33

    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 use
    
    SQL>
    

    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.

提交回复
热议问题