Temporary tables are visible to all operations in the same session. So you cannot create a temporary table of the same name in the same session before you drop the one that exists (commit the transaction in your case).
You may want to use:
CREATE TEMP TABLE tmptbl IF NOT EXISTS ...
More about CREATE TABLE
in the manual.
Unique temp tables
To make the temp table local per "thread" (in the same session) you need to use unique table names. One way would be to use an unbound SEQUENCE
and dynamic SQL - in a procedural language like plpgsql or in a DO statement (which is basically the same without storing a function.
Run one:
CREATE SEQUENCE myseq;
Use:
DO $$
BEGIN
EXECUTE 'CREATE TABLE tmp' || nextval('myseq') ||'(id int)';
END;
$$
To know the latest table name:
SELECT 'tmp' || currval('myseq');
Or put it all into a plpgsql function and return the table or reuse the table name.
All further SQL commands have to be executed dynamically, though, as plain SQL statements operate with hard coded identifiers. So, it is probably best, to put it all into a plpgsql function.
Unique ID to use same temp table
Another possible solution could be to use the same temp table for all threads in the same session and add a column thread_id
to the table. Be sure to index the column, if you make heavy use of the feature. Then use a unique thread_id
per thread (in the same session).
Once only:
CREATE SEQUENCE myseq;
Once per thread:
CREATE TEMP TABLE tmptbl(thread_id int, col1 int) IF NOT EXISTS;
my_id := nextval('myseq'); -- in plpgsql
-- else find another way to assign unique id per thread
SQL:
INSERT INTO tmptbl(thread_id, col1) VALUES
(my_id, 2), (my_id, 3), (my_id, 4);
SELECT * FROM tmptbl WHERE thread_id = my_id;
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…