>"PRAGMA foreign_keys = ?" is a property of the connection only, not the >database file. So what advantage would there be in including the PRAGMA >statements in the body of a transaction?
Not much, if I do everything right, I guess. But what if I break the foreign key integrity? If it's inside a transaction, I can rollback easily, given that I realize I broke it. But if I don't, because foreign key checks are turned off, and I commit everything before noticing that something's wrong, that's a lot harder to fix. I can either take extra care not to break anything, or just do a backup of the database file before 'risky' transactions, but it would be much easier if I could just use deferred foreign keys that don't let me commit if the database is in an inconsistent state. Máté Dan Kennedy <danielk1...@gmail.com> ezt írta (időpont: 2018. nov. 23., P, 16:30): > On 11/23/2018 09:54 PM, szmate1618 wrote: > > Dear list members, > > > > I have the following problem, with which I'd like to request your aid: > > > > Currently, at version 3.25.2, SQLite only has a limited support for alter > > table. E.g. you cannot change the datatype (type affinity) of a column, > or > > drop a column. > > > > The usual workaround is to create a new table with the desired schema, > fill > > it with data from the original table, drop the original table, and rename > > the new one. But what if the original table is a parent table in a > foreign > > key relationship? > > > > The official solution > > <https://www.sqlite.org/lang_altertable.html#otheralter> is turning > foreign > > keys off, making the changes you want, then turning foreign keys on. But > > I'm slightly annoyed this cannot be done in a transaction (because these > PRAGMA > > foreign_keys =s don't take effect inside of transactions, so they need to > > be issued before and after). > > > "PRAGMA foreign_keys = ?" is a property of the connection only, not the > database file. So what advantage would there be in including the PRAGMA > statements in the body of a transaction? > > Dan. > > > > > > > I'd like to use deferred foreign keys instead. I have 3 queries, one of > > them seems to work, the two others do not. My questions are the > following: > > > > - Does the seemingly working query work by design? Or it's just a > > fortunate(?) constellation of multiple factors, and depending on other > > tables or new data in the database it might break in the future? > Somewhat > > like undefined behavior in C++? > > - Why do the other ones not work? How are they different from the > first > > one? > > > > Setup > > > > PRAGMA foreign_keys = OFF; > > DROP TABLE IF EXISTS Parent;CREATE TABLE Parent(A TEXT UNIQUE, > > COLUMN_TO_DROP FLOAT);INSERT INTO Parent VALUES('whatever', 0.0); > > DROP TABLE IF EXISTS Child;CREATE TABLE Child(C TEXT REFERENCES > > Parent(A) DEFERRABLE INITIALLY DEFERRED);INSERT INTO Child > > VALUES('whatever'); > > > > PRAGMA foreign_keys = ON; > > > > Query1 - seems to be working as intended > > > > BEGIN TRANSACTION;CREATE TABLE Temp AS SELECT A FROM Parent;DROP TABLE > > Parent;CREATE TABLE Parent (A TEXT UNIQUE);INSERT INTO Parent SELECT * > > FROM Temp;DROP TABLE Temp;COMMIT; > > > > Query2 - create [...] as select [...] fails > > > > BEGIN TRANSACTION;CREATE TABLE Temp AS SELECT A FROM Parent;DROP TABLE > > Parent;CREATE TABLE Parent AS SELECT * FROM Temp; -- different > > from Query1CREATE UNIQUE INDEX ParentIndex on Parent(A); -- different > > from Query1DROP TABLE Temp;COMMIT; > > > > Result: > > > > sqlite> PRAGMA foreign_key_check; > > sqlite> .schemaCREATE TABLE Child(C TEXT REFERENCES Parent(A) > > DEFERRABLE INITIALLY DEFERRED);CREATE TABLE Parent(A TEXT);CREATE > > UNIQUE INDEX ParentIndex on Parent(A); > > sqlite> SELECT * FROM Parent; > > whatever > > > > Query3 - insert into [...] fails > > > > BEGIN TRANSACTION;CREATE TABLE Temp (A TEXT UNIQUE); -- different > > from Query1INSERT INTO Temp SELECT A FROM Parent; -- different from > > Query1DROP TABLE Parent;CREATE TABLE Parent (A TEXT UNIQUE);INSERT > > INTO Parent SELECT * FROM Temp;DROP TABLE Temp;COMMIT; > > > > Result: > > > > sqlite> PRAGMA foreign_key_check; > > sqlite> .schemaCREATE TABLE Child(C TEXT REFERENCES Parent(A) > > DEFERRABLE INITIALLY DEFERRED);CREATE TABLE Parent (A TEXT UNIQUE); > > sqlite> SELECT * FROM Parent; > > whatever > > > > Note that PRAGMA foreign_key_check does not report any problem in any of > > the cases. > > > > > > I posted an identical question on StackOverflow, but no one was able to > > provide any information so far. Thanks in advance! > > > > Máté Szabó > > _______________________________________________ > > sqlite-users mailing list > > sqlite-users@mailinglists.sqlite.org > > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users > > > > _______________________________________________ > sqlite-users mailing list > sqlite-users@mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users > _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users