views:

24

answers:

1

I have two tables linked by a foreign key. Example:

"CREATE TABLE one (id INTEGER PRIMARY KEY, data REAL, time TEXT NOT NULL DEFAULT (datetime('now')));"

"CREATE TABLE two (id INTEGER PRIMARY KEY, parent INTEGER, CONSTRAINT fc_two FOREIGN KEY (parent) REFERENCES one(id));"

So I'd like to do an INSERT INTO with an embedded JOIN, but I already tried (and then Googled it) and apparently it doesn't work. I did find a way to do it using something called @@Identity but that doesn't seem to work with SQLite. Basically, I need to:

  1. Insert data into one
  2. Find the value of "id" for the row I just inserted into one
  3. Insert data into two using the id value I just got from one

1 and 3 are easy, but to get 2 I would need to query for the one I just inserted. None of the data columns (except id) are unique, and the one unique combination (the set of all non-id columns as a whole is unique, just not any individual one) is impossible to reliably query against.

What's the best way to perform this operation?

A: 
SELECT last_insert_rowid()
cement
Nice, that does work. However, I now have another problem. Using last_insert_rowid() in an INSERT statement works fine, but then the next INSERT statement fails. I need to somehow "store" that temporary value and use it in multiple INSERT statements into the second table. Any thoughts on how to do this?
jfm429
So what stops you from saving value of last_insert_rowid() to a variable and providing it within other parameters (as selectionArgs) for further insert statements?
cement
The issue is that if I execute a SQLite statement and grab the value, then execute another SQLite statement using the value, it uses two statements. I'm not sure if this is an issue for locking, since technically a single transaction should be a single SQLite statement because in between the two inserts, the database is in an inconsistent state. If I break up the statement (SQL statement -> C variable -> SQL Statement) it breaks up the transaction. I'd like a way to keep it all within a single string of SQL... or is that not a problem to split it up like that?
jfm429
It will not be a problem if you will use db.beginTransaction(), then do all your insert operations and call db.setTransactionSuccessful(), db.endTransaction().
cement
SQLite doesn't have a beginTransaction() function; transactions are handled in the SQL code; however, all statements from the BEGIN TRANSACTION and END TRANSACTION statements must be contained in a single block of SQL. That's my problem; I can't store intermediate values within that SQL block in SQLite.
jfm429
SQLite doesn't have beginTransaction(). But SQLiteDatabase class does have all methods listed in my comment above.
cement
There is no such thing as SQLiteDatabase in SQLite. SQLite is C; it's not object-oriented. There also is no sqlite3_*() function that seems to work in that manner. If there is I'd like to know about it.
jfm429
Sorry. Don't know why, but I thought you are using android. Have you tried to declare sqlite variable and select identity in it? Then you can use variable value for your insert operations.
cement
SQLite doesn't support variables... at least I can't figure out how they would work. It looks like using a temporary table is the only way to do it.
jfm429
In any case, it looks like the temporary table will work. It would be nice to have variables in SQLite, but oh well. Thanks for your help!
jfm429