Czy coś takiego jest możliwe?
INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));
jak użycie wartości zwracanej jako wartości do wstawienia wiersza w drugiej tabeli z odniesieniem do pierwszej tabeli?
postgresql
sql-returning
Eike Cochu
źródło
źródło
rows
z(some_query returning ...)
pracy może w dzisiejszych czasach (nie próbowałem).Najlepsza praktyka w tej sytuacji. Użyj
RETURNING … INTO
.INSERT INTO teams VALUES (...) RETURNING id INTO last_id;
Zwróć uwagę, że dotyczy to PLPGSQL
źródło
RETURNING ... INTO
.Zgodnie z odpowiedzią udzieloną przez Denisa de Bernardy.
Jeśli chcesz, aby identyfikator został również zwrócony później i chcesz wstawić więcej rzeczy do Tabeli2:
with rows as ( INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id ) INSERT INTO Table2 (val, val2, val3) SELECT id, 'val2value', 'val3value' FROM rows RETURNING val
źródło
DO $$ DECLARE tableId integer; BEGIN INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id INTO tableId; INSERT INTO Table2 (val) VALUES (tableId); END $$;
Testowane z psql (10.3, serwer 9.6.8)
źródło
Możesz użyć
lastval()
funkcji:Więc coś takiego:
INSERT INTO Table1 (name) VALUES ('a_title'); INSERT INTO Table2 (val) VALUES (lastval());
Będzie to działać dobrze, o ile nikt nie wywoła
nextval()
żadnej innej sekwencji (w bieżącej sesji) między Twoimi INSERTami.Jak Denis zauważył poniżej, a ja ostrzegałem powyżej, użycie
lastval()
możenextval()
spowodować kłopoty, jeśli uzyskasz dostęp do innej sekwencji, używając między swoimi INSERTami. Mogłoby się to zdarzyć, gdyby istniał wyzwalacz INSERT naTable1
tym, który ręcznie wywołałnextval()
sekwencję, lub, co bardziej prawdopodobne, wykonał INSERT na tabeli z kluczem podstawowymSERIAL
lubBIGSERIAL
. Jeśli chcesz być naprawdę paranoikiem (dobrze, w końcu oni naprawdę są tobą, aby cię dopaść), możesz użyć,currval()
ale musisz znać nazwę odpowiedniej sekwencji:INSERT INTO Table1 (name) VALUES ('a_title'); INSERT INTO Table2 (val) VALUES (currval('Table1_id_seq'::regclass));
Sekwencja generowana automatycznie jest zwykle nazywana,
t_c_seq
gdziet
jest nazwą tabeli ic
jest nazwą kolumny, ale zawsze możesz się tego dowiedzieć, wchodząc dopsql
i mówiąc:a następnie spojrzeć na domyślną wartość danej kolumny, na przykład:
FYI:
lastval()
jest mniej więcej wersją MySQL dla PostgreSQLLAST_INSERT_ID
. Wspominam o tym tylko dlatego, że wiele osób lepiej zna MySQL niż PostgreSQL, więc odsyłanielastval()
do czegoś znajomego może wyjaśnić sprawę.źródło
lastval
polega na tym, że za plecami może znajdować się sekwencja oparta na INSERT z wyzwalacza AFTER INSERT w Table1. Byłoby to w bieżącej sesji i prawdopodobnie zmieniłoby się,lastval()
gdy się tego nie spodziewasz.INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id
źródło