Local Temporary table in Oracle 10 (for the scope of Stored Procedure)

前端 未结 4 405
小鲜肉
小鲜肉 2020-11-30 15:24

I am new to oracle. I need to process large amount of data in stored proc. I am considering using Temporary tables. I am using connection pooling and the application is mult

相关标签:
4条回答
  • 2020-11-30 16:05

    You say you are new to Oracle. I'm guessing you are used to SQL Server, where it is quite common to use temporary tables. Oracle works differently so it is less common, because it is less necessary.

    Bear in mind that using a temporary table imposes the following overheads:

    1. read data to populate temporary table
    2. write temporary table data to file
    3. read data from temporary table as your process starts
    Most of that activity is useless in terms of helping you get stuff done. A better idea is to see if you can do everything in a single action, preferably pure SQL.


    Incidentally, your mention of connection pooling raises another issue. A process munging large amounts of data is not a good candidate for running in an OLTP mode. You really should consider initiating a background (i.e. asysnchronous) process, probably a database job, to run your stored procedure. This is especially true if you want to run this job on a regular basis, because we can use DBMS_SCHEDULER to automate the management of such things.

    0 讨论(0)
  • 2020-11-30 16:15

    I used global temporary table recently and it was behaving very unwantedly manner.

    I was using temp table to format some complex data in a procedure call and once the data is formatted, pass the data to fron end (Asp.Net). In first call to the procedure, i used to get proper data and any subsequent call used to give me data from last procedure call in addition to current call.

    I investigated on net and found out an option to delete rows on commit. I thought that will fix the problem.. guess what ? when i used on commit delete rows option, i always used to get 0 rows from database. so i had to go back to original approach of on commit preserve rows, which preserves the rows even after commiting the transaction.This option clears rows from temp table only after session is terminated. then i found out this post and came to know about the column to track call_id of a session.

    I implemented that solution and still it dint fix the problem. then i wrote following statement in my procedure before i starting any processing.

    Delete From Temp_table;

    Above statemnet made the trick. my front end was using connection pooling and after each procedure call it was commitng the transaction but still keeping the connection in connection pool and subsequent request was using the same connection and hence the database session was not terminated after every call.. Deleting rows from temp table before strating any processing made it work....

    It drove me nuts till i found this solution....

    0 讨论(0)
  • 2020-11-30 16:28

    IF you're using transaction (rather than session) level temporary tables, then this may already do what you want... so long as each call only contains a single transaction? (you don't quite provide enough detail to make it clear whether this is the case or not)

    So, to be clear, so long as each call only contains a single transaction, then it won't matter that you're using a connection pool since the data will be cleared out of the temporary table after each COMMIT or ROLLBACK anyway.

    (Another option would be to create a uniquely named temporary table in each call using EXECUTE IMMEDIATE. Not sure how performant this would be though.)

    0 讨论(0)
  • 2020-11-30 16:29

    In Oracle, it's almost never necessary to create objects at runtime.

    Global Temporary Tables are quite possibly the best solution for your problem, however since you haven't said exactly why you need a temp table, I'd suggest you first check whether a temp table is necessary; half the time you can do with one SQL what you might have thought would require multiple queries.

    That said, I have used global temp tables in the past quite successfully in applications that needed to maintain a separate "space" in the table for multiple contexts within the same session; this is done by adding an additional ID column (e.g. "CALL_ID") that is initially set to 1, and subsequent calls to the procedure would increment this ID. The ID would necessarily be remembered using a global variable somewhere, e.g. a package global variable declared in the package body. E.G.:

    PACKAGE BODY gtt_ex IS
       last_call_id integer;
       PROCEDURE myproc IS
          l_call_id integer;
       BEGIN
          last_call_id := NVL(last_call_id, 0) + 1;
          l_call_id      := last_call_id;
          INSERT INTO my_gtt VALUES (l_call_id, ...);
          ...
          SELECT ... FROM my_gtt WHERE call_id = l_call_id;
       END;
    END;
    

    You'll find GTTs perform very well even with high concurrency, certainly better than using ordinary tables. Best practice is to design your application so that it never needs to delete the rows from the temp table - since the GTT is automatically cleared when the session ends.

    0 讨论(0)
提交回复
热议问题