Re: [sqlite] Trouble with constraints and triggers
On 23/09/2010 11:52 p.m., Richard Hipp wrote: >> Josh Gibbswrote: >>> CREATE TABLE Message (message_id INTEGER PRIMARY KEY AUTOINCREMENT, >>> Subject TEXT); >>> CREATE TABLE MessageRecipient (message_id INTEGER REFERENCES >>> Message(message_id) ON DELETE CASCADE, recipient_ID INTEGER REFERENCES >>> Recipient(recipient_id)); >>> CREATE TABLE Recipient (recipient_ID INTEGER PRIMARY KEY AUTOINCREMENT, >>> name); >>> >>> I've tried creating a trigger after delete on MessageRecipient to remove >> the >>> referenced Recipient, and this works if it's the only related item, >>> however any >>> other MessageRecipient relationship causes the delete to fail. As there >>> is no >>> 'or ignore' for the delete statement, I can't get this to keep my data >>> clean. > > DELETE FROM recipient > WHERE recipient_id = old.recipient_id > AND NOT EXISTS(SELECT 1 FROM message_recipient > WHERE recipient.recipient_id= > message_recipient.recipient_id); > This works perfectly, thanks. ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Trouble with constraints and triggers
Josh Gibbswrote: > On 23/09/2010 3:15 p.m., Igor Tandetnik wrote: >> You could do something like >> >> delete from Recipient where recipient_ID = old.recipient_ID and >>recipient_ID not in (select recipient_ID from MessageRecipient); >> > > That was the last idea we had as well. Trouble is MessageRecipient > contains hundreds > of thousands of records. Would that cipple the speed of the delete, or > would the query > apply the 'not in' to the sub-select on its index? If there is an index on MessageRecipient(recipient_ID), the query should use it. Alternatively, you could maintain a reference count in Recipient (with still more triggers), and delete the record once the count reaches zero. -- Igor Tandetnik ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Trouble with constraints and triggers
On Wed, Sep 22, 2010 at 11:15 PM, Igor Tandetnikwrote: > Josh Gibbs wrote: > > CREATE TABLE Message (message_id INTEGER PRIMARY KEY AUTOINCREMENT, > > Subject TEXT); > > CREATE TABLE MessageRecipient (message_id INTEGER REFERENCES > > Message(message_id) ON DELETE CASCADE, recipient_ID INTEGER REFERENCES > > Recipient(recipient_id)); > > CREATE TABLE Recipient (recipient_ID INTEGER PRIMARY KEY AUTOINCREMENT, > > name); > > > > I've tried creating a trigger after delete on MessageRecipient to remove > the > > referenced Recipient, and this works if it's the only related item, > > however any > > other MessageRecipient relationship causes the delete to fail. As there > > is no > > 'or ignore' for the delete statement, I can't get this to keep my data > > clean. > > You could do something like > > delete from Recipient where recipient_ID = old.recipient_ID and > recipient_ID not in (select recipient_ID from MessageRecipient); > DELETE FROM recipient WHERE recipient_id = old.recipient_id AND NOT EXISTS(SELECT 1 FROM message_recipient WHERE recipient.recipient_id= message_recipient.recipient_id); > > -- > Igor Tandetnik > > ___ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > -- D. Richard Hipp d...@sqlite.org ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Trouble with constraints and triggers
On 23/09/2010 3:15 p.m., Igor Tandetnik wrote: > Josh Gibbswrote: >> CREATE TABLE Message (message_id INTEGER PRIMARY KEY AUTOINCREMENT, >> Subject TEXT); >> CREATE TABLE MessageRecipient (message_id INTEGER REFERENCES >> Message(message_id) ON DELETE CASCADE, recipient_ID INTEGER REFERENCES >> Recipient(recipient_id)); >> CREATE TABLE Recipient (recipient_ID INTEGER PRIMARY KEY AUTOINCREMENT, >> name); >> >> I've tried creating a trigger after delete on MessageRecipient to remove the >> referenced Recipient, and this works if it's the only related item, >> however any >> other MessageRecipient relationship causes the delete to fail. As there >> is no >> 'or ignore' for the delete statement, I can't get this to keep my data >> clean. > You could do something like > > delete from Recipient where recipient_ID = old.recipient_ID and >recipient_ID not in (select recipient_ID from MessageRecipient); > That was the last idea we had as well. Trouble is MessageRecipient contains hundreds of thousands of records. Would that cipple the speed of the delete, or would the query apply the 'not in' to the sub-select on its index? ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Trouble with constraints and triggers
Josh Gibbswrote: > CREATE TABLE Message (message_id INTEGER PRIMARY KEY AUTOINCREMENT, > Subject TEXT); > CREATE TABLE MessageRecipient (message_id INTEGER REFERENCES > Message(message_id) ON DELETE CASCADE, recipient_ID INTEGER REFERENCES > Recipient(recipient_id)); > CREATE TABLE Recipient (recipient_ID INTEGER PRIMARY KEY AUTOINCREMENT, > name); > > I've tried creating a trigger after delete on MessageRecipient to remove the > referenced Recipient, and this works if it's the only related item, > however any > other MessageRecipient relationship causes the delete to fail. As there > is no > 'or ignore' for the delete statement, I can't get this to keep my data > clean. You could do something like delete from Recipient where recipient_ID = old.recipient_ID and recipient_ID not in (select recipient_ID from MessageRecipient); -- Igor Tandetnik ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
[sqlite] Trouble with constraints and triggers
Hi all, I'm hoping someone can assist me with a problem I'm having creating a cascading delete operation as well as a constraint. This table is an example of the layout of my data: CREATE TABLE Message (message_id INTEGER PRIMARY KEY AUTOINCREMENT, Subject TEXT); CREATE TABLE MessageRecipient (message_id INTEGER REFERENCES Message(message_id) ON DELETE CASCADE, recipient_ID INTEGER REFERENCES Recipient(recipient_id)); CREATE TABLE Recipient (recipient_ID INTEGER PRIMARY KEY AUTOINCREMENT, name); My goal is that when I remove an item from the Message table, all of the related items in the MessageRecipient table are removed, and all items from the Recipient table that no longer have references to the MessageRecipient are removed. The tables as listed above fulfill the need for a Recipient to exist, prevent a Recipient from being removed if a MessageRecipient still points to them, and removes the MessageRecipient when the Message is deleted. It does not fulfill tidying up of the Recipient table, and items are left orphaned when all Messages are removed that refer to that recipient. I've tried creating a trigger after delete on MessageRecipient to remove the referenced Recipient, and this works if it's the only related item, however any other MessageRecipient relationship causes the delete to fail. As there is no 'or ignore' for the delete statement, I can't get this to keep my data clean. Any solutions to this conundrum would be greatly appreciated. Thanks, Josh ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users