Tabele tymczasowe są widoczne dla wszystkich operacji w tej samej sesji. Więc nie możesz utwórz tabelę tymczasową o tej samej nazwie w tej samej sesji zanim odrzucisz ten, który istnieje (zatwierdź transakcję w swoim przypadku).
Możesz użyć:
CREATE TEMP TABLE tmptbl IF NOT EXISTS ...
Więcej o CREATE TABLE
w instrukcji.
Unikalne tabele tymczasowe
Aby tabela tymczasowa była lokalna dla „wątku” (w tej samej sesji), musisz użyć unikalnych nazw tabel . Jednym ze sposobów byłoby użycie niezwiązanej SEQUENCE
i dynamiczny SQL - w języku proceduralnym, takim jak plpgsql lub w instrukcji DO (co jest zasadniczo takie samo bez przechowywania funkcji).
Uruchom jeden:
CREATE SEQUENCE myseq;
Użyj:
DO $$
BEGIN
EXECUTE 'CREATE TABLE tmp' || nextval('myseq') ||'(id int)';
END;
$$
Aby poznać najnowszą nazwę tabeli:
SELECT 'tmp' || currval('myseq');
Lub umieść to wszystko w funkcji plpgsql i zwróć tabelę lub użyj ponownie nazwy tabeli.
Wszystkie dalsze polecenia SQL muszą być jednak wykonywane dynamicznie, ponieważ zwykłe instrukcje SQL operują na sztywno zakodowanych identyfikatorach. Więc prawdopodobnie najlepiej jest umieścić to wszystko w funkcji plpgsql.
Unikalny identyfikator do używania tej samej tabeli tymczasowej
Innym możliwym rozwiązaniem może być użycie tej samej tabeli tymczasowej dla wszystkich wątków w tej samej sesji i dodaj kolumnę thread_id
na stół. Pamiętaj, aby zaindeksować kolumnę, jeśli intensywnie korzystasz z tej funkcji. Następnie użyj unikalnego thread_id
na wątek (w tej samej sesji).
Tylko raz:
CREATE SEQUENCE myseq;
Raz na wątek:
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;