Skip to Main Content
  • Questions
  • Concurrency and global temporary tables

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, oj.

Asked: August 08, 2019 - 9:25 pm UTC

Last updated: August 12, 2019 - 3:41 am UTC

Version: 12

Viewed 1000+ times

You Asked

I have a ruby program that needs to load a lot of data from different views concurrently using large IN clauses. Regular sql gives me PGA limit error. My next approach is to create a function that takes in an array of ids and a sql statement, inserts the ids into a global temporary table then runs the sql query using exists on the global temporary table. This seems to work fine when run serially but errors out when done concurrently.

Here's my global temporary_table. This table has been pre-created and is never dropped.`p`p
CREATE GLOBAL TEMPORARY TABLE temp_id_table (
  id NUMBER
)
on commit preserve rows;



Here's my package
CREATE OR REPLACE PACKAGE test.bulk_query
IS
  TYPE temp_ids IS TABLE OF NUMBER;

  FUNCTION run_query(ids IN temp_ids, query IN VARCHAR2) RETURN sys_refcursor;

END bulk_query;
/

CREATE OR REPLACE PACKAGE BODY test.bulk_query
IS
  /* Retrieve data for syncing
   */
  FUNCTION run_query(ids IN temp_ids, query IN VARCHAR2) RETURN sys_refcursor
  IS
    dataset SYS_REFCURSOR;
  BEGIN
    FOR i IN 1 .. ids.count LOOP
      execute immediate 'INSERT INTO TEMP_ID_TABLE (ID) VALUES (:id)' using ids(i);
    END LOOP;

    OPEN dataset FOR query;

    commit;

    RETURN dataset;
  END;
END bulk_query;
/


The error that I'm getting when run concurrently is this:
ORA-00955: name is already used by an existing object


Again, when run serially, it finishes fine. I am not using a connection pool. What am I doing wrong?

and Connor said...

Sorry, I'm dubious on:

This table has been pre-created and is never dropped


because if that were the case, then why would your code contain

    FOR i IN 1 .. ids.count LOOP
      execute immediate 'INSERT INTO TEMP_ID_TABLE (ID) VALUES (:id)' using ids(i);
    END LOOP;


You'd only need that be done dynamically (execute immediate) if there was a possibility that TEMP_ID_TABLE did not exist.

So I suspect something is trying to *create* that table on the fly.

Rating

  (1 rating)

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

Comments

Concurrency and global temporary tables

oj bucao, August 09, 2019 - 1:55 pm UTC

I was under the wrong impression that I needed to use dynamic sql to use the id variable. I changed the function to use straight sql and I'm still getting the same error. I am definitely not re-creating the global temporary table everytime. Again I'm only getting the error when I'm running concurrent queries.
Connor McDonald
August 12, 2019 - 3:41 am UTC

We need to see *all* of the code then

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