Foreign key definition in sqlite - sqlite

Cant add foreign key constraint in sqlite ...........

As of SQLite 3.6.19, SQLite supports foreign keys. You need to enable them via:
sqlite> PRAGMA foreign_keys = ON;
They are turned off by default for backwards compatibility.
See the documentation for more details.

sqlite does not enforce foreign key constraints.

in sqlite 3 :
examples :
create table student (_id integer autoincrement primary key ,master_id integer);
create table master (_id integer autoincrement primary key , name varchar(30) );
select * from student where master_id in (select _id from master where name like '...')
Don not need foreign key (master_id) references master(_id) ;
:)

Related

Foreign key mismatch SQLite

I searched all the documentation about this and I can't seem to understans what's the problem, maybe an experienced could help me.
So I'm creating a table called LOCALIZACAO:
CREATE TABLE LOCALIZACAO(
id INTEGER PRIMARY KEY AUTOINCREMENT,
rua TEXT NOT NULL,
codigoPostal TEXT NOT NULL,
UNIQUE (codigoPostal));
And this other table that references LOCALIZACAO, called SOCIOLOCALIZACAO:
CREATE TABLE SOCIOLOCALIZACAO(
idS INTEGER REFERENCES SOCIO(idS),
idL INTEGER NOT NULL REFERENCES LOCALIZACAO(idL),
CONSTRAINT pk_SOCIOLOCALIZACAO PRIMARY KEY (idS),
CONSTRAINT fk_SOCIOLOCALIZACAO FOREIGN KEY (idL) REFERENCES LOCALIZACAO(id) ON DELETE CASCADE ON UPDATE CASCADE);
Altough I'm inserting elements on the LOCALIZACAO table, when I'm inserting on the SOCIOLOCALIZACAO table:
INSERT INTO SOCIOLOCALIZACAO VALUES (1,1);
I'm given an error
foreign key mismatch "SOCIOLOCALIZACAO" referencing "LOCALIZACAO"
I'm sure there is the element 1 in SOCIO and in LOCALIZACAO
Here is the SOCIO table:
CREATE TABLE SOCIO(
id INTEGER PRIMARY KEY AUTOINCREMENT,
nome TEXT NOT NULL,
anoDeNascimento INTEGER NOT NULL,
numeroDeSocio INTEGER NOT NULL CHECK (numeroDeSocio > 0),
nif INTEGER NOT NULL CHECK (nif > 99999999 AND nif < 1000000000),
anoDeVinculacao INTEGER NOT NULL CHECK (anoDeNascimento < anoDeVinculacao),
UNIQUE (nome, nif),
UNIQUE (numeroDeSocio));
Any help is appreciated!
Thank you!
Your foreign key references the fields idS and idL in table LOCALIZACAO. There are no such fields, there's only an id field there.
I guess you're only seeing this when inserting records because SQLite is not very pedantic. Other databases wouldn't have let you create such a foreign key.

JDBC ignores SQLite foreign key constraint ON DELETE action

I've a Rate table with the following structre:
CREATE TABLE Rate (
id INTEGER PRIMARY KEY AUTOINCREMENT,
book_id INTEGER,
value INTEGER,
user_id INTEGER,
FOREIGN KEY(user_id) REFERENCES User(ID),
FOREIGN KEY(book_id) REFERENCES book(ID) ON DELETE RESTRICT
)
And a book table with the following structure:
DROP TABLE IF EXISTS Book;
CREATE TABLE Book (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL,
ISBN VARCHAR,
author_id INTEGER,
editor_id INTEGER,
translator_id INTEGER,
publisher_id INTEGER,
"type" VARCHAR,
language VARCHAR,
"date" VARCHAR,
format VARCHAR,
summary TEXT,
FOREIGN KEY(author_id) REFERENCES Author(ID) ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY(editor_id) REFERENCES Editor(ID) ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY(translator_id) REFERENCES Translator(ID) ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY(publisher_id) REFERENCES Publisher(ID) ON DELETE SET NULL ON UPDATE CASCADE
);
So, if I have a Rate entry like this:
1 1 4 3(ID, BOOK_ID, VALUE, USER_ID)
I shouldn't be able to delete the Book with the ID 1, right?
This is exactly what happens when I try to delete the Book with ID 1 on SQLITE Manager. It gives me
FOREIGN KEY constraint failed
However, when I call my delete from the code, it totally ignores the restriction and deletes the book and there's no change in the Rate entry it is still:
1 1 4 3
And my delete method is like the following:
public void delete() {
try {
String query = "DELETE FROM book WHERE id = ? ";
PreparedStatement statement = db.prepareStatement(query);
statement.setInt(1, (Integer) this.id);
statement.executeUpdate();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
When i run PRAGMA foreign_keys on SQLITE Manager it returns 1. So, I assume that the database is created correctly.
The documentation says:
... foreign key constraints ... must still be enabled by the application at runtime, using the PRAGMA foreign_keys command. For example:
PRAGMA foreign_keys = ON;
Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection.

sqlite column constraints both unique and foreign

Does sqlite allow a column to be both unique and a foreign key at the same time?
How does the definition look like?
CREATE TABLE table1 (
id INTEGER PRIMARY KEY,
fkey INTEGER NOT NULL UNIQUE REFERENCES table2(id)
)
CREATE TABLE table2 (
id INTEGER PRIMARY KEY
)
Sure
CREATE TABLE table1 (
id INTEGER PRIMARY KEY,
fkey INTEGER NOT NULL UNIQUE,
FOREIGN KEY(fkey) REFERENCES table2(id)
)
result.
Query executed successfully: CREATE TABLE table1 (
id INTEGER PRIMARY KEY,
fkey INTEGER NOT NULL UNIQUE,
FOREIGN KEY(fkey) REFERENCES table2(id)
) (took 0ms)
REMEMBER. As of version 3.6.19, SQLite supports foreign key constraints. But enforcement of foreign key constraints is turned off by default (for backwards compatibility). To enable foreign key constraint enforcement, run PRAGMA foreign_keys=ON, from http://sqlite.org/faq.html

foreign key mismatch on delete command for unrelated record

I have the following 5 tables defined with a few records inserted into the 1st 4. This is using sqlite 3.7.1.7 with foreign key constaint enabled.
create table if not exists subject (id varchar(50) primary key,desc varchar(100));
insert into subject (id,desc) values ("subject1","test subject");
create table if not exists subjectlevel (id_subject_id varchar(50) references subject(id) on delete cascade, id integer not null, desc varchar(100) not null, questmcmaxselections integer not null, primary key (id_subject_id,id));
insert into subjectlevel (id_subject_id,id,desc,questmcmaxselections) values ("subject1",1,"test subject1 level 1",4);
insert into subjectlevel (id_subject_id,id,desc,questmcmaxselections) values ("subject1",2,"test subject1 level 2",4);
create table if not exists questmc (id integer primary key, text varchar(300) not null, includeallanswers int not null, subject_id varchar(50), subjectlevel_id integer, foreign key (subject_id, subjectlevel_id) references subjectlevel (id_subject_id,id) on delete cascade);
insert into questmc (text,includeallanswers,subject_id,subjectlevel_id) values ("this is a _ question", 1, "subject1",1);
create table if not exists questmcselection (id integer primary key, text varchar(100) not null, subject_id varchar(50), subjectlevel_id integer, foreign key (subject_id, subjectlevel_id) references subjectlevel (id_subject_id,id) on delete cascade);
insert into questmcselection (text,subject_id,subjectlevel_id) values ("this is a solution","subject1",1);
create table if not exists questmc_questmcselection(id integer primary key, answer integer not null, questmc_id integer, questmcselection_id integer, subject_id varchar(50), subjectlevel_id integer, foreign key (questmc_id) references questmc(id) on delete cascade, foreign key (questmcselection_id) references questmcselection (id) on delete cascade, foreign key (subject_id,subjectlevel_id) references questmc (subject_id,subjectlevel_id) on delete cascade, foreign key (subject_id,subjectlevel_id) references questmcselection (subject_id,subjectlevel_id));
if i attempt to delete the second record in the subjectlevel table, i get a foreign key mismatch error as long as table questmc_questmcselection is defined.
sqlite> delete from subjectlevel where id=2;
Error: foreign key mismatch - "questmc_questmcselection" referencing "questmcselection"
questmc, questmcselection, and questmc_questmcselection have no related existing records that should prevent this deletion. Any idea why this error occurs?
This error has nothing to do with this particular subjectlevel record.
Your problem is that your tables lack the required indexes.
This was not reported earlier because that DELETE statement was the first command that required SQLite to check the consistency of the database schema.
Based on CL's answer -
sqlite> create table parent(a);
sqlite> create table child(a, FOREIGN KEY (a) REFERENCES parent(a));
sqlite> pragma foreign_keys = ON;
sqlite> insert into parent values(3);
sqlite> insert into child values (3);
Error: foreign key mismatch - "child" referencing "parent"
sqlite> create unique index p_a on parent(a);
sqlite> insert into child values (3);
sqlite> _
From the documentation:
Usually, the parent key of a foreign key constraint is the primary key
of the parent table. If [not], then the parent key columns must be
collectively subject to a UNIQUE constraint or have a UNIQUE index [which uses]
the collation sequences ... in the CREATE TABLE
statement for the parent table.
i.e. the alternative is:
sqlite> create table parent(a, b, UNIQUE (a, b));
sqlite> create table child (x, y, FOREIGN KEY (x, y) REFERENCES parent(a, b));
(this also highlights multi-column foreign keys; they work with indexes too...)

Foreign Key constraint doesn't work

I have two tables, theme and quiz, here is their definition:
CREATE TABLE "theme" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "nom" VARCHAR NOT NULL );
CREATE TABLE quiz(
id INTEGER PRIMARY KEY,
nom VARCHAR(256) NOT NULL,
theme INTEGER NOT NULL,
niveau INTEGER NOT NULL,
pass INTEGER DEFAULT 1 NOT NULL,
jok INTEGER DEFAULT 1 NOT NULL,
etat INTEGER DEFAULT 0 NOT NULL,
FOREIGN KEY (theme) REFERENCES theme(id)
);
The field id (the primary key) in the table theme is a Foreign Key in the quiz table.
When i try to insert a record in the table quiz which contain the value 30 for example as a foreign key, the record is inserted successfully in the quiz table although there is no record in the theme table with the id = 30, i mean, wasn't supposed to interdict this insert since i had a Foreign key constraint?
Are you sure foreign key support is enabled?
Assuming the library is compiled with foreign key constraints enabled,
it must still be enabled by the application at runtime, using the
PRAGMA foreign_keys command. For example:
sqlite> PRAGMA foreign_keys = ON;

Resources