Chcę wstawić dane do 3 tabel za pomocą jednego zapytania.
Moje tabele wyglądają jak poniżej:
CREATE TABLE sample (
id bigserial PRIMARY KEY,
lastname varchar(20),
firstname varchar(20)
);
CREATE TABLE sample1(
user_id bigserial PRIMARY KEY,
sample_id bigint REFERENCES sample,
adddetails varchar(20)
);
CREATE TABLE sample2(
id bigserial PRIMARY KEY,
user_id bigint REFERENCES sample1,
value varchar(10)
);
Otrzymam klucz w zamian za każde włożenie i muszę wstawić ten klucz do następnej tabeli.
Moje zapytanie to:
insert into sample(firstname,lastname) values('fai55','shaggk') RETURNING id;
insert into sample1(sample_id, adddetails) values($id,'ss') RETURNING user_id;
insert into sample2(user_id, value) values($id,'ss') RETURNING id;
Ale jeśli uruchamiam pojedyncze zapytania, po prostu zwracają mi wartości i nie mogę ich natychmiast użyć ponownie w następnym zapytaniu.
Jak to osiągnąć?
INSERT INTO sample1 (user_id, adddetails)
nie powinno tak być w Twojej odpowiedzi(sample_id, addetails)
?Coś takiego
with first_insert as ( insert into sample(firstname,lastname) values('fai55','shaggk') RETURNING id ), second_insert as ( insert into sample1( id ,adddetails) values ( (select id from first_insert), 'ss') RETURNING user_id ) insert into sample2 ( id ,adddetails) values ( (select user_id from first_insert), 'ss');
Ponieważ wygenerowany identyfikator z wstawiania do
sample2
nie jest potrzebny, usunąłemreturning
klauzulę z ostatniej wstawki.źródło
Zazwyczaj używałbyś transakcji, aby uniknąć pisania skomplikowanych zapytań.
http://www.postgresql.org/docs/current/static/sql-begin.html
http://dev.mysql.com/doc/refman/5.7/en/commit.html
Możesz także użyć CTE, zakładając, że twój znacznik Postgres jest poprawny. Na przykład:
with sample_ids as ( insert into sample(firstname, lastname) values('fai55','shaggk') RETURNING id ), sample1_ids as ( insert into sample1(id, adddetails) select id,'ss' from sample_ids RETURNING id, user_id ) insert into sample2(id, user_id, value) select id, user_id, 'val' from sample1_ids RETURNING id, user_id;
źródło
Możesz utworzyć wyzwalacz po wstawieniu w tabeli Sample, aby wstawić go do pozostałych dwóch tabel.
Jedynym problemem, jaki widzę, jest to, że nie będziesz mieć możliwości wstawiania adddetails, zawsze będzie on pusty lub w tym przypadku ss. Nie ma możliwości wstawienia kolumny do próbki, której nie ma w tabeli próbek, więc nie można jej wysłać razem z wkładką wewnętrzną.
Inną opcją byłoby utworzenie procedury składowanej do uruchamiania wstawek.
Masz pytanie taged mysql i postgressql o jakiej bazie danych tu mówimy?
źródło