Pix wrote: > Suppose I've some tables like these: > > CREATE TABLE contacts (ID, name, surname); > CREATE TABLE oldContacts (ID, name, surname); > CREATE TABLE messages (message, contactID, contactWasDeleted default > NULL); > > I wrote a trigger similar to this: > > CREATE TRIGGER OnDeleteContact BEFORE DELETE ON Contacts > FOR EACH ROW > BEGIN > INSERT INTO OldContacts (name, surname) VALUES (old.name, > old.surname); UPDATE messages SET contactID = last_insert_rowid(), > contactWasDeleted=true WHERE contactID = old.id AND > contactWasDeleted=false; END; > > Actually, when I delete a row in Contacts, the trigger create a new > row > in OldContacts and updates the messages.contactID field... > The matter is that "last_insert_rowid()" doesn't return the ID of the > item inserted by the trigger but returns a previously created ID.... > (or 0 if no item was inserted) > > I think that the problem is that last_insert_rowid() is evaluated > BEFORE performing the "INSERT INTO etc..." statement... > > There is a way to have the right last_inserted_rowid() ?
Paolo, Your problem arises because the ID columns are not the same as the rowid of the records. In order for a column to be used as the rowid for a table, that column must be declared with type of INTEGER PRIMARY KEY. For your trigger to work as you want you need to change the definition of the ID column in the oldContacts table to INTEGER PRIMARY KEY. This will cause the ID values to be auto assigned and have the same vallues returned by last_insert_rowid(). The following trace shows the correct operation. Note you can see the difference between the rowid and your ID column in the dumps of the contacts table (which does not have ID declared INTEGER PRIMARY KEY). SQLite version 2.8.13 Enter ".help" for instructions sqlite> .read test_lir.sql CREATE TABLE contacts (ID, name, surname); CREATE TABLE oldContacts (ID INTEGER PRIMARY KEY, name, surname); CREATE TABLE messages (message, contactID, contactWasDeleted default 'F'); CREATE TRIGGER OnDeleteContact BEFORE DELETE ON Contacts FOR EACH ROW BEGIN INSERT INTO OldContacts (name, surname) VALUES (old.name, old.surname); UPDATE messages SET contactID = last_insert_rowid(), contactWasDeleted = 'T' WHERE contactID = old.id AND contactWasDeleted = 'F'; END; insert into contacts values (10, 'John', 'Doe'); insert into contacts values (20, 'Fred', 'Flintstone'); insert into messages values (101, 10, 'F'); insert into messages values (102, 20, 'F'); mode column header on select rowid,* from contacts; rowid ID name surname ---------- ---------- ---------- ---------- 1 10 John Doe 2 20 Fred Flintstone select rowid,* from oldContacts; select rowid,* from messages; rowid message contactID contactWasDeleted ---------- ---------- ---------- ----------------- 1 101 10 F 2 102 20 F delete from contacts where ID = 20; select rowid,* from contacts; rowid ID name surname ---------- ---------- ---------- ---------- 1 10 John Doe select rowid,* from oldContacts; rowid ID name surname ---------- ---------- ---------- ---------- 1 1 Fred Flintstone select rowid,* from messages; rowid message contactID contactWasDeleted ---------- ---------- ---------- ----------------- 1 101 10 F 2 102 1 T delete from contacts where id = 10; select rowid,* from contacts; select rowid,* from oldContacts; rowid ID name surname ---------- ---------- ---------- ---------- 1 1 Fred Flintstone 2 2 John Doe select rowid,* from messages; rowid message contactID contactWasDeleted ---------- ---------- ---------- ----------------- 1 101 2 T 2 102 1 T sqlite> P.S. Note that SQL doesn't have a boolean data type with values true and false. These are normally replaced with a single character code as I have done above. The entire words 'True' and 'False' could be used just as well, but they will simply take up more space in the database file. I hope this helps. Dennis Cote --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]