PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

thread safety postgresql per tabelle temporanee

Le tabelle temporanee sono visibili a tutte le operazioni nella stessa sessione. Quindi non puoi crea una tabella temporanea con lo stesso nome nella stessa sessione prima di eliminare quello esistente (commetti la transazione nel tuo caso).

Potresti voler usare:

CREATE TEMP TABLE tmptbl IF NOT EXISTS ...

Ulteriori informazioni su CREATE TABLE nel manuale.

Tabelle temporanee uniche

Per rendere la tabella temporanea locale per "thread" (nella stessa sessione) è necessario utilizzare nomi di tabella univoci . Un modo sarebbe usare una SEQUENCE non vincolata e SQL dinamico - in un linguaggio procedurale come plpgsql o in un'istruzione DO (che è sostanzialmente la stessa senza memorizzare una funzione.

Esegui uno:

CREATE SEQUENCE myseq;

Usa:

DO $$
BEGIN
EXECUTE 'CREATE TABLE tmp' || nextval('myseq')  ||'(id int)';
END;
$$

Per conoscere il nome della tabella più recente:

SELECT 'tmp' || currval('myseq');

Oppure inserisci tutto in una funzione plpgsql e restituisci la tabella o riutilizza il nome della tabella.

Tutti gli altri comandi SQL devono essere eseguiti dinamicamente, tuttavia, poiché le semplici istruzioni SQL operano con identificatori codificati. Quindi, probabilmente è meglio, mettere tutto in una funzione plpgsql.

ID univoco per utilizzare la stessa tabella temporanea

Un'altra possibile soluzione potrebbe essere quella di utilizzare la stessa tabella temporanea per tutti i thread nella stessa sessione e aggiungi una colonna thread_id al tavolo. Assicurati di indicizzare la colonna, se fai un uso intenso della funzione. Quindi usa un thread_id univoco per thread (nella stessa sessione).

Una sola volta:

CREATE SEQUENCE myseq;

Una volta 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;