Wow, that's some clever use. I tried doing it all in one go using a `vars` table (name, value, timestamp) and a `dummy` (empty table to enable access to case syntax) table, made a mess of case...when...then... only to realize that a then-expr can't contain insert clause. I guess I'll implement this in DAL itself.
On Wed, Feb 20, 2019 at 9:15 PM David Raymond <david.raym...@tomtom.com> wrote: > 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 > _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users