PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

postgresql-Thread-Sicherheit für temporäre Tabellen

Temporäre Tabellen sind für alle Operationen in derselben Sitzung sichtbar. Sie können also nicht Erstellen Sie eine temporäre Tabelle mit demselben Namen in derselben Sitzung bevor Sie die vorhandene löschen (in Ihrem Fall die Transaktion festschreiben).

Sie können Folgendes verwenden:

CREATE TEMP TABLE tmptbl IF NOT EXISTS ...

Mehr über CREATE TABLE im Handbuch.

Eindeutige temporäre Tabellen

Um die temporäre Tabelle pro "Thread" (in derselben Sitzung) lokal zu machen, müssen Sie eindeutige Tabellennamen verwenden . Eine Möglichkeit wäre die Verwendung einer ungebundenen SEQUENCE und dynamisches SQL - in einer prozeduralen Sprache wie plpgsql oder in einer DO-Anweisung (was im Grunde dasselbe ist, ohne eine Funktion zu speichern.

Führen Sie eins aus:

CREATE SEQUENCE myseq;

Verwendung:

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

So erfahren Sie den neuesten Tabellennamen:

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

Oder packen Sie alles in eine plpgsql-Funktion und geben Sie die Tabelle zurück oder verwenden Sie den Tabellennamen wieder.

Alle weiteren SQL-Befehle müssen jedoch dynamisch ausgeführt werden, da reine SQL-Anweisungen mit fest codierten Bezeichnern arbeiten. Daher ist es wahrscheinlich am besten, alles in eine plpgsql-Funktion zu packen.

Eindeutige ID zur Verwendung derselben temporären Tabelle

Eine andere mögliche Lösung könnte darin bestehen, dieselbe temporäre Tabelle zu verwenden für alle Threads in derselben Sitzung und fügen Sie eine Spalte thread_id hinzu an den Tisch. Achten Sie darauf, die Spalte zu indizieren, wenn Sie die Funktion stark nutzen. Verwenden Sie dann eine eindeutige thread_id pro Thread (in derselben Sitzung).

Einmal:

CREATE SEQUENCE myseq;

Einmal pro 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;