postgresql thread safety for temporary tables

后端 未结 1 974
你的背包
你的背包 2020-12-18 07:20

This the syntax I use for creating a temporary table:

create temp table tmpTable (id bigint not null, primary key (id)) on commit drop;

I k

相关标签:
1条回答
  • 2020-12-18 07:31

    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;
    
    0 讨论(0)
提交回复
热议问题