> At the very least, do the initial INSERT and get-last in a > single transaction.
Not necessarily. You can do INSERT and get-last without starting transaction because get-last is per-connection, not per-database. So the only thing that should be taken care of is no inserts are executed on the connection between your initial INSERT and get-last. > Also be careful with triggers. Triggers can muck everything up by > changing the "last." Also false. Triggers don't change the value returned by last_insert_rowid(). Or it's better say they change it but only within the trigger context, when trigger exits value is reverted to that been set before trigger executed. Read http://www.sqlite.org/c3ref/last_insert_rowid.html carefully. Pavel On Thu, Jan 7, 2010 at 11:16 AM, Jay A. Kreibich <j...@kreibi.ch> wrote: > On Thu, Jan 07, 2010 at 03:39:42PM +0000, Simon Slavin scratched on the wall: >> >> On 7 Jan 2010, at 1:15pm, Jay A. Kreibich wrote: >> >> > There isn't a correct way of doing this. You need to manually loop >> > over the SELECT, do the INSERT, and call sqlite3_last_insert_rowid() >> > (or the SQL function last_insert_rowid()) after each INSERT to build >> > up a collection of ROWIDs. >> >> One other aspect is this: you are taking what should be an internal >> function of SQLite and using it for your own purposes. > > Both the C and SQL functions are there to be used. Proper foreign > key support is nearly impossible without them. I'd guess that's > why the SQL version of the function exists. > >> This is sometimes a bad idea. > > Well, yes, just about anything can be abused. The sqlite3_sequence > table, for example. > >> If you want to have a column with particular >> values in which you use for your own purposes, make your own column >> and put whatever values into it you want. > > Yes and no. Using the raw ROWID column for application purposes-- > especially foreign keys-- is not a good idea. One .dump or VACUUM > and you're screwed. > > That said, within the SQLite environment the proper and recognized > way of doing unique, auto-generated ID values is using an INTEGER > PRIMARY KEY, and it is well understood that this is a ROWID alias. > If you want to setup foreign key references (the most common reason > to need the generated ID value of a row that was just INSERTed, > and what I assume the OP is trying to do), you need a function like > this or some other way to get the new ROWID-- that is, the new > application defined ID-- for this table. > > So proper use does make some assumptions. For starters, the rows > should be INSERTed into a table that has an INTEGER PRIMARY KEY. > In other words, the function should be thought of as > "sqlite3_last_insert_integer_primary_key()" (but I'm really glad it > isn't named that). > > Second, if you INSERT a record, grab the ROWID/PRIMARY KEY via > sqlite3_last_insert_rowid(), and then INSERT one or more rows > into a different table that contains a foreign key reference > back to the original table, you should do that whole sequence > within a transaction to make sure you get the proper "last" ROWID. > Of course, you should likely be doing that all within a transaction > anyways. At the very least, do the initial INSERT and get-last in a > single transaction. > > Also be careful with triggers. Triggers can muck everything up by > changing the "last." > > -j > > -- > Jay A. Kreibich < J A Y @ K R E I B I.C H > > > "Our opponent is an alien starship packed with atomic bombs. We have > a protractor." "I'll go home and see if I can scrounge up a ruler > and a piece of string." --from Anathem by Neal Stephenson > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users