On Fri, Feb 05, 2010 at 06:42:34PM -0500, German Escallon scratched on the wall:
> create table X(xid integer primary key); > create table Y(yid integer primary key, y_xid references X(xid) ); > create table Z(zid integer primary key, z_xid references X(xid) ); > > create table Y_Z > ( > yzid integer primary key autoincrement, > yz_yid references Y(yid), /*references primary key in y */ > yz_zid references Z(zid), /* references primary key in z */ > CHECK > ( > (select y_xid from Y where yid= yz_yid ) = (select z_xid from > Z where zid= yz_zid ) > ) > ); OK, this is a tad on the ugly side, but it might work. Basically I'm having rows in y_z carry around a copy of the xid from the two tables. The CHECK constraint then becomes simple. I've fiddled with the names a bit to keep things straight in my head. Yes, some of the UNIQUEs are redundant, but they're required for the FKs to work correctly. ---------------------------------------------------------------------- PRAGMA foreign_keys = 1; CREATE TABLE x ( xid INTEGER PRIMARY KEY ); CREATE TABLE y ( yid INTEGER PRIMARY KEY, xid INTEGER REFERENCES x ( xid ), UNIQUE ( yid, xid ) ); CREATE TABLE z ( zid INTEGER PRIMARY KEY, xid INTEGER REFERENCES x ( xid ), UNIQUE ( zid, xid ) ); CREATE TABLE y_z ( yzid INTEGER PRIMARY KEY AUTOINCREMENT, yid INTEGER, y_xid INTEGER, zid INTEGER, z_xid INTEGER, FOREIGN KEY ( yid, y_xid ) REFERENCES y ( yid, xid ), FOREIGN KEY ( zid, z_xid ) REFERENCES z ( zid, xid ), CHECK ( y_xid == z_xid ) ); INSERT INTO x ( xid ) VALUES ( 1 ); INSERT INTO x ( xid ) VALUES ( 2 ); INSERT INTO y ( yid, xid ) VALUES ( 111, 1 ); INSERT INTO y ( yid, xid ) VALUES ( 112, 1 ); INSERT INTO y ( yid, xid ) VALUES ( 121, 2 ); INSERT INTO y ( yid, xid ) VALUES ( 122, 2 ); INSERT INTO z ( zid, xid ) VALUES ( 211, 1 ); INSERT INTO z ( zid, xid ) VALUES ( 212, 1 ); INSERT INTO z ( zid, xid ) VALUES ( 221, 2 ); INSERT INTO z ( zid, xid ) VALUES ( 222, 2 ); -- this should work: INSERT INTO y_z ( yid, y_xid, zid, z_xid ) VALUES ( 111, 1, 211, 1 ); -- fails check constraint: INSERT INTO y_z ( yid, y_xid, zid, z_xid ) VALUES ( 111, 1, 221, 2 ); -- fails foreign key constraint ( there is no y(221,1) ) INSERT INTO y_z ( yid, y_xid, zid, z_xid ) VALUES ( 111, 1, 221, 1 ); ---------------------------------------------------------------------- Of course, the INSERT on y_z gets... interesting. There are ways to reduce that, however. Maybe something like: INSERT INTO y_z ( yid, y_xid, zid, z_xid ) VALUES ( ?1, ( SELECT xid FROM y WHERE yid = ?1 ), ?2, ( SELECT xid FROM z WHERE zid = ?2 ) ); You might even be able to work that into a trigger so you can just insert yid and zid and the trigger fills in the y_xid and z_xid. Actually... come to think of it, you might just build a trigger into your original schema. You can't put a sub-select into a CHECK, but you can put one in a trigger. Try an INSERT/UPDATE trigger that makes sure all the references line up and throws an error if they do not. -j > Jusding by this diagram > <http://www.sqlite.org/syntaxdiagrams.html#table-constraint> I thought > my last create table statement was syntactically correct. But I got the > following message: > "Error: subqueries prohibited in CHECK constraints".. Uhmm.. Bummer. > > Here's some background to my problem. > > Table (X) is referenced by two other tables (Y & Z). This are > one-to-many relationships (for every record in X there are 0 or more > records in both Y, and in Z). > Now.. I also have a many-to-many relationship between Y & Z (for every > record in Y there are 0 or more records in Z, and for every record in Z > there are 0 or more records in Y). > So, I created a table Y_Z to keep track of this relationship. If I > remove the check constraint that is causing the error, how can I ensure > that all Y_Z entries associate entries that reference the same record in > X? In other words, say I have.. > > insert into X (xid) values(1); > insert into X (xid) values(2); > insert into Y (yid, y_xid) values (1, 1); /* references entry 1 in X */ > insert into Z (zid, z_xid) values (1, 2); /* references entry 2 in X */ > > I need a constraint that would fail the following statement, and > maintain my data integrity. > > insert into Y_Z( yz_yid, yz_xid) values (1, 1). > > Is there any alternative you can suggest? Thank you in advance. > > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users -- 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