pragma busy_timeout not working - sqlite

I am trying to view and change the busy_timeout parameter in a SQLite database, but I can not view the output from pragma busy_timeout.
sqlite> PRAGMA busy_timeout = 1000;
sqlite> PRAGMA busy_timeout;
sqlite>
What am I doing wrong here?
SQLite version 3.7.10
sqlite> pragma compile_options;
ENABLE_FTS3
ENABLE_RTREE
TEMP_STORE=1
THREADSAFE=1

PRAGMA busy_timeout was added in version 3.7.15.

Related

When does Cascade Delete Commit in Sqlite?

This is my sql set of statements:
char *sql = "BEGIN TRANSACTION;
CREATE TABLE Friends(id varchar UNIQUE);
CREATE TABLE Enemies(id2 varchar ,id3 INTEGER,CONSTRAINT id_econst
FOREIGN KEY(id2) REFERENCES Friends(id) ON DELETE CASCADE);
INSERT INTO Friends VALUES('11');
INSERT INTO Friends VALUES('2');
INSERT INTO Enemies VALUES('11',3);
INSERT INTO Enemies VALUES('3',5);
END TRANSACTION;
PRAGMA foreign_keys = ON;
DELETE FROM Friends WHERE id = '11';";
Performs cascade delete on the Enemies table, whereas :
char *sql = "BEGIN TRANSACTION;
CREATE TABLE Friends(id varchar UNIQUE);
CREATE TABLE Enemies(id2 varchar ,id3 INTEGER,CONSTRAINT id_econst
FOREIGN KEY(id2) REFERENCES Friends(id) ON DELETE CASCADE);
INSERT INTO Friends VALUES('11');
INSERT INTO Friends VALUES('2');
INSERT INTO Enemies VALUES('11',3);
INSERT INTO Enemies VALUES('3',5);
PRAGMA foreign_keys = ON;
DELETE FROM Friends WHERE id = '11';
END TRANSACTION;";
does normal delete.
Why is it so ?
You are enabling foreign key support within the transaction. To quote sqlite:
This pragma is a no-op within a transaction
https://sqlite.org/pragma.html#pragma_foreign_keys
In your second example, the pragma has no effect, and the foreign key constraint is not enforced.

PRAGMA recursive_triggers won't disable recursive triggers

I do not understand trigger recursion in SQLite 3.8.6.
From my understanding setting PRAGMA recursive_triggers to 0 should prevent a trigger from triggering another one.
But here is an example of what actually happens for me:
sqlite> PRAGMA recursive_triggers;
0
sqlite> CREATE TABLE t1(a TEXT, b TEXT, c TEXT);
sqlite> CREATE TRIGGER on_insert AFTER INSERT ON t1
...> BEGIN
...> UPDATE t1 SET b="c" WHERE rowid=NEW.rowid;
...> END;
sqlite> CREATE TRIGGER on_update_b AFTER UPDATE OF b ON t1
...> BEGIN
...> SELECT RAISE(fail,"triggered update b!");
...> END;
sqlite> INSERT INTO t1 VALUES("a","b","c");
Error: triggered update b!
I probably misunderstood something...
Is it possible to prevent the on_update_b trigger to be triggered?
These triggers are not recursive.
A trigger is recursive if it triggers itself (directly or indirectly).
This would be the case if on_update_b would execute an UPDATE or INSERT.

PRAGMA foreign_key_check;

I am trying to use PRAGMA foreign_key_check; without success :(
I have made some foreign keys violations on a database (with PRAGMA foreign_keys = OFF;), then I set this to true then launched PRAGMA foreign_key_check; but this did not return any results.
However, when I try to insert the very same lines with foreign keys violations with PRAGMA foreign_keys = ON; I do get a foreign key constraint violation error.
I am using SQLite 3.7.3.
Is there something I am missing regarding this command? Is there a bug?
Thanks
EDIT: I have just tried with 3.8.3.1 (higher version this time ;) ) but cannot get any results though :(
However, some other commands seem to not work as expected (especially .schema !?):
SQLite version 3.8.3.1 2014-02-11 14:52:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> attach "D:\MusicLib_Minimal_TEST_FOREIGN_KEYS.db" as db1;
sqlite> .schema device
sqlite> PRAGMA foreign_keys=ON;
sqlite> PRAGMA foreign_keys;
1
sqlite> PRAGMA foreign_key_check;
sqlite> select * from device
...> ;
1|test|/|/|0|0
sqlite> select * from playlist
...> ;
sqlite> PRAGMA integrity_check;
ok
sqlite> .dump device
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
COMMIT;
sqlite> PRAGMA table_info(device);
0|idDevice|INTEGER|1||1
1|name|TEXT|1||0
2|source|TEXT|1||0
3|destination|TEXT|1||0
4|idPlaylist|INTEGER|1||0
5|idMachine|INTEGER|1||0
sqlite>
PRAGMA foreign_key_check was added in sqlite 3.7.16. You have an older version.
Unknown pragmas are just no-ops; no errors are emitted.
I have found out the solution :) Problem was a misuse (or bug ?) of sqlite3.exe
When calling sqlite3.exe without parameters, a main empty database is created, and looks like the commands does not apply the attached db:
D:\>sqlite3.exe
SQLite version 3.8.3.1 2014-02-11 14:52:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> attach "D:\MusicLib_Minimal_TEST_FOREIGN_KEYS.db" as db1
...> ;
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main
2 db1 D:\MusicLib_Minimal_TEST_FOREIGN_KEYS.db
sqlite> .tables
db1.device db1.libType db1.optiontype db1.playlist
db1.file db1.machine db1.path db1.statement
db1.genre db1.option db1.playCounter db1.statsource
sqlite> .schema db1.device
sqlite> .exit
If opening database as an argument of sqlite3.exe, it works as expected:
D:\>sqlite3.exe MusicLib_Minimal_TEST_FOREIGN_KEYS.db
SQLite version 3.8.3.1 2014-02-11 14:52:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main D:\MusicLib_Minimal_TEST_FOREIGN_KEYS.db
sqlite> .tables
device genre machine optiontype playCounter statement
file libType option path playlist statsource
sqlite> .schema device
CREATE TABLE "device" (
"idDevice" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"name" TEXT NOT NULL,
"source" TEXT NOT NULL,
"destination" TEXT NOT NULL,
"idPlaylist" INTEGER NOT NULL,
"idMachine" INTEGER NOT NULL,
FOREIGN KEY(idPlaylist) REFERENCES playlist(idPlaylist),
FOREIGN KEY(idMachine) REFERENCES machine(idMachine)
);
sqlite> PRAGMA foreign_keys;
0
sqlite> PRAGMA foreign_keys=ON;
sqlite> PRAGMA foreign_keys;
1
sqlite> PRAGMA foreign_key_check;
device|1|machine|0
device|1|playlist|1
sqlite> select * from device
...> ;
1|test|/|/|0|0
sqlite> select * from playlist
...> ;
sqlite> select * from machine
...> ;

Is it allowed to have null foreign key in sqlite when PRAGMA foreign_keys=ON?

according to this null foreign keys are allowed unless and until we are adding the appropriate "NOT NULL" constraint to the schema.
but I am seeing the some different behavior,
sqlite> PRAGMA Foreign_keys;
1
sqlite> create table proc (
sqlite> pid integer,
sqlite> name text,
sqlite> ppid integer,
sqlite> foreign key (ppid) references proc (id)
sqlite> );
sqlite> .schema proc
CREATE TABLE proc (
pid integer,
name text,
ppid integer,
foreign key (ppid) references proc (id)
);
sqlite> insert into proc (pid, name, ppid)
sqlite> values (0, "init", null);
Error: foreign key mismatch
sqlite> PRAGMA Foreign_keys=OFF;
sqlite> PRAGMA Foreign_keys;
0
sqlite> insert into proc (pid, name, ppid)
sqlite> values (0, "init", null);
sqlite> select * from proc;
0|init|
how can I allow null foreign key in sqlite when PRAGMA foreign_keys=ON? or it is not possible at all?
The ID column is named pid, not id.
The parent key column must have a UNIQUE or PRIMARY KEY constraint.
Try adding a foreign key clause by changing your table create statement to:
CREATE TABLE proc (pid integer, name text, ppid integer, foreign key (ppid) references
proc (id) ON UPDATE CASCADE ON DELETE SET NULL);

SQLite [Err] 21 - not an error

I have the following code in SQL
-- SCHEMA VERSION: 2
-- Pre-update actions
PRAGMA foreign_keys = OFF;
-- end
-- Create HARVEST_PERIOD table
CREATE TABLE "main"."HARVEST_PERIOD" (
"ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"CODE" TEXT(64) NOT NULL,
"PERIOD" TEXT(64) NOT NULL,
"CURRENT_STATE" TEXT(128)
)
;
-- Post-update actions
INSERT OR REPLACE INTO "main"."SETTINGS" ("NAME", "VALUE") values ("SchemaVersion", "2");
PRAGMA foreign_keys = ON;
-- end
The new table is created as expected and the settings table updated as expected, too. What could be the reason for getting this: [Err] 21 - not an error
Is there any better suggested way to create the new schema?
I encounter this error as well. Later I figured it out. It's because another application was connected to the same db. So, my application can't modify the db -- create a table.
I created it successfully just by closing the another db connection.

Resources