Well, you _can_ with this specific simplified schema, but it's a little sketchy and most likely will not scale. So if at all possible this sort of thing should be done from the controlling program rather than by a trigger. Also as mentioned, if the a/b/c _attribute fields aren't unique in the tables then it will also just result in duplication. So not the most useful. But hey, here's my solution for the over simplified version:
As you said we don't have variables, so last_insert_rowid() can't get saved for each table. For this specific schema though the lack of "not null" on the foreign keys makes it doable, as long as "not null" is the actual expectation and nothing in the m2m table stays around with a null. create trigger trg_summary_insert instead of insert on summary for each row begin insert into Beta (b_attribute) values (new.b_attribute); insert into m2mAlphaBeta (FK_b_id) select last_insert_rowid(); --This leaves FK_a_id null. insert into Alpha (a_attribute) values (new.a_attribute); update m2mAlphaBeta set FK_a_id = last_insert_rowid() where FK_a_id is null; --Only the new row inserted above should have a null, so the new row gets updated --without us needing to know the rowid for the m2m table. --And since the previous statement was an update, --then last_insert_rowid() will keep the value from the Alpha insert. insert into Charlie (c_attribute, FK_C_a_id) values (new.c_attribute, last_insert_rowid()); end; sqlite> insert into summary values ('A', 1.0, 'One'), ('B', 2.2, 'Two'); sqlite> select * from summary; a_attribute|b_attribute|c_attribute A|1.0|One B|2.2|Two sqlite> select * from Alpha; a_id|a_attribute 1|A 2|B sqlite> select * from Beta; b_id|b_attribute 1|1.0 2|2.2 sqlite> select * from Charlie; c_id|c_attribute|FK_C_a_id 1|One|1 2|Two|2 sqlite> select * from m2mAlphaBeta; _id|FK_a_id|FK_b_id 1|1|1 2|2|2 --Throw in junk values to make sure it's not just because of coincidence that the new rowid's are the same for each table sqlite> insert into Alpha values (17, 'Seventeen'); sqlite> insert into Beta values (32, 32.0); sqlite> insert into Charlie values (57, 'Fifty-Seven', null); --And try it again sqlite> insert into summary values ('C', 3.3, 'Three'); sqlite> select * from summary; a_attribute|b_attribute|c_attribute A|1.0|One B|2.2|Two C|3.3|Three --However, this just blindly throws in duplicates since there're no unique constraints sqlite> insert into summary values ('C', 3.3, 'Three'); sqlite> select * from summary; a_attribute|b_attribute|c_attribute A|1.0|One B|2.2|Two C|3.3|Three C|3.3|Three sqlite> Also at the very end here I realize this also requires no triggers on inserts for any of the real tables. Otherwize last_insert_rowid() will be giving results from the inserts in the recursive triggers, and throw things off. So yes, if possible do it in the controlling program rather than in triggers :) -----Original Message----- From: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] On Behalf Of Rocky Ji Sent: Wednesday, February 20, 2019 6:14 AM To: SQLite mailing list Subject: [sqlite] What is the recommended way to write to views? Hi everyone, I know the simple answer to be `instead of insert ...`. But consider a situation where: Alpha has-many Beta,and Beta has-many Alpha Alpha has-many Charlie, while Charlie has one Alpha So if my SQL looks like: -- PRAGMA fk ON; create table Alpha ( a_id integer primary key autoincrement, a_attribute text ); create table Beta ( b_id integer primary key autoincrement, b_attribute real ); create table Charlie ( c_id integer primary key autoincrement, c_attribute text, FK_C_a_id integer, constraint abc foreign key (FK_C_a_id) references Alpha (a_id) ); create table m2mAlphaBeta ( _id integer primary key autoincrement, FK_a_id integer, FK_b_id integer, constraint def foreign key (FK_a_id) references Alpha (a_id), constraint ghi foreign key (FK_b_id) references Beta (b_id) ); create view summary as select a.a_attribute, b.b_attribute, c.c_attribute from m2mAlphaBeta m inner join Alpha a on a.a_id = m.FK_a_id inner join Beta b on b.b_id = m.FK_b_id inner join Charlie c on c.FK_C_a_id = a.a_id ; And assuming all incoming data (say from CSV read) is correct. How do I write a record to `summary`? Like how do I get ROWID of the "just inserted" record in A to insert into C properly. I am thinking "should I make transactions, but we don't have variables"... and going round-and-round without solution. Please recommend the canonical way to write to such views. Good day. _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users