PostgreSQL: Jak uzyskać wartość ID wygenerowaną przez typ SERIAL i użyć jej w kolejnym zapytaniu?

5-lis-2022

SERIAL generuje kolejne wartości, zazwyczaj używane jako identyfikator w tabelach. Np. tutaj kolumna id ma automatycznie nadawaną wartość:

CREATE TABLE t1
(id SERIAL,
 name TEXT
);

a tutaj id trzeba podawać samodzielnie:

CREATE TABLE t2
(id INT,
 name TEXT
);

Co zrobić, jeśli chcielibyśmy w zapytaniu SQL wykorzystać wartość, która została wygenerowana w kolejnym zapytaniu? Oto propozycja nr 1

Polecenie INSERT wstawia nowy rekord. Podczas tego wstawiania generowana jest nowa wartość id. Ta wartość jest zwracana przez klauzulę RETURNING. Żeby z tej wartości dalej skorzystać budujemy wyrażeni CTE (Common Table Expression), które wartości zwracane przez INSERT z RETURNING udostępnia w wirtualnej tablicy r. Idąc dalej można wykonać zapytanie do tabeli r, a wynik np. wykorzystać do wstawienia go do kolejnej tabeli t2:

WITH r AS
(INSERT INTO t1(name) VALUES('x323') RETURNING id, name) 
INSERT INTO t2(id, name)
SELECT * FROM r;

A oto propozycja nr 2.

Polecenie insert generuje nową wartość w oparciu o sekwencję (tak właśnie działa typ SERIAL). Możemy wiec w kolejnym zapytaniu pobrać wartość z tej sekwencji poleceniem currval. Co istotne zadziała to nawet wtedy, jeśli w międzyczasie w innej sesji ktoś też wstawił rekord do tabeli t1 i wygenerował nową wartość:

INSERT INTO t1(name) VALUES('c');
SELECT * FROM t1 WHERE id = currval('t1_id_seq');

 

Komentarze są wyłączone

Autor: Rafał Kraik