views:

6196

answers:

4

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 multi-threaded.

Is there a way to create temporary tables in a way that different table instances are created for every call to the stored procedure, so that data from multiple stored procedure calls does not mix up?

+3  A: 

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.)

cagcowboy
+1: you don't need to recreate temporary tables for each session. Create a temporary table ONCE and each session will only see its own data.
Vincent Malgrat
+2  A: 

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.

Jeffrey Kemp
+1 for the suggestion to skip using temporary tables
Rob van Wijk
+5  A: 
APC
A: 

Hi All,

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....

Amit