Can not add a second foreign key when creating table - sqlite

I am creating a table with 2 foreign keys
but whenever I have the second key, it will return an error:
CREATE TABLE reviews(
id INTEGER PRIMARY KEY,
stars INT,
business_id INT,
FOREIGN KEY(business_id) REFERENCES businesses(id),
user_id INT,
FOREIGN KEY (user_id) REFERENCES users(id)
);
It will throw syntax error near user_id, and if I put business_id after user_id, it will throw syntax error near business_id...
And if I only put one foreign key there, it will just create the table, tried several times. What's the problem here?
users and businesses are two tables, I'm creating a junction table for them.

Don't mix column definition with constraint definition. Columns first, constraints after:
CREATE TABLE reviews(
id INTEGER PRIMARY KEY,
stars INT,
business_id INT,
user_id INT,
FOREIGN KEY(business_id) REFERENCES businesses(id),
FOREIGN KEY (user_id) REFERENCES users(id)
);

Related

Sqlite foreign key mismatch?

I've read this question and understood the referenced foreign keys to be unique, but somehow the insertion to table are still throwing foreign key mismatch errors:
CREATE TABLE medication (
med_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
med_name VARCHAR (20) NOT NULL,
dosage VARCHAR (10)
);
CREATE TABLE disease (
dis_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
disease_name VARCHAR (20) NOT NULL
);
CREATE TABLE dis_med (
disease_id int NOT NULL,
medication_id int NOT NULL,
CONSTRAINT PK_dis_med PRIMARY KEY (disease_id, medication_id),
CONSTRAINT FK_dis FOREIGN KEY (disease_id) REFERENCES disease (dis_id),
CONSTRAINT FK_med FOREIGN KEY (medication_id) REFERENCES medication (med_id));
CREATE TABLE user_disease (
user_id REFERENCES user (user_id),
dis_id REFERENCES disease (dis_id),
med_id REFERENCES dis_med(medication_id),
CONSTRAINT PK_dis_user PRIMARY KEY (user_id, dis_id)
);
Through the list in the question I cited:
the parent table (medication, disease) exists.
the parent columns exist
the child table references all of the primary key columns in the parent table
Update1
I was able to insert data and bypass the error by altering the user_disease table by composite foreign key. I'd appreciate it if someone can point out what's the best design here. Many thanks in advance!
CREATE TABLE user_disease (
user_id REFERENCES user (user_id),
dis_id REFERENCES disease (dis_id),
med_id REFERENCES dis_med(medication_id),
CONSTRAINT FK_dis_med FOREIGN KEY REFERENCES dis_med(disease_id, medication_id),
CONSTRAINT PK_dis_user PRIMARY KEY (user_id, dis_id)
);
From SQLite Foreign Key Support/3. Required and Suggested Database Indexes:
Usually, the parent key of a foreign key constraint is the primary key of the parent table.
If they are not the primary key, then the parent key columns must be collectively
subject to a UNIQUE constraint or have a UNIQUE index.
With this:
CREATE TABLE user_disease (
...........................
med_id REFERENCES dis_med(medication_id),
...........................
);
the column med_id of user_disease references the column medication_id of dis_med, which is not the PRIMARY KEY of dis_med and there is no UNIQUE constraint for it. It just references med_id of medication .
Why do you need the column med_id in user_disease?
You have dis_id referencing disease, which may also be used to retrieve from dis_med (all) the row(s) from dis_med for that disease.

Unable to insert data into table with foreign key in oracle11g

CREATE TABLE Client_master (
Client_no varchar(6) PRIMARY KEY,
Name varchar(15) NOT NULL,
City varchar(15),
Pincode number(8),
State varchar(15),
Bal_due Number(10,2),
CHECK(Client_no LIKE 'C%'));
INSERT INTO
Client_master(Client_no,Name,City,Pincode,State,Bal_due)
VALUES('C00001','Ivan Bayross','Bombay','400054','Maharashtra',15000);
1 row created.
CREATE TABLE Sales_order(
Order_no varchar(6) PRIMARY KEY REFERENCES Client_master (Client_no),
Order_date date,
Client_no varchar(6),
Dely_type char(1) DEFAULT 'f',
Billed_yn char(1),
Salesman_no varchar(6),
Dely_date date,
Order_status varchar(10),
CHECK(Order_no LIKE 'O%'),
CHECK(Order_status IN ('inprocess','backorder','cancelled')),
CHECK(Dely_date>Order_date));
INSERT INTO Sales_order(Order_no, Order_date, Client_no, Dely_type, Billed_yn, Salesman_no, Dely_date, Order_status)
VALUES('C19001','12-jan-96','C00001','f','n','S0001','20-jan-96','inprocess');
INSERT INTO
*
ERROR at line 1:
ORA-02291: integrity constraint (SYSTEM.SYS_C007155) violated - parent key not
found
Please help me insert data into Child table.
What's this SYSTEM.SYS_C007155 error? Why this error message "parent key is not found"?
The parent key not found is because you have a foreign key in your sales_order table which is pointing to the client_master, and there is no matching key value - exactly what it says. But it's because you've done something odd:
Sales_order(Order_no varchar(6) PRIMARY KEY REFERENCES Client_master (Client_no)
You've made the order_no the primary key for this table, but also made it a foreign key to the client_no on the other table. Your insert uses order_no of 'C19001', which doesn't match the client_no you previously inserted into the parent table.
You almost certainly wanted sales_order.client_no to be a foreign key to client_master.client_no, so you would have the references... against that column:
CREATE TABLE Sales_order(Order_no varchar(6) PRIMARY KEY,
Order_date date,
Client_no varchar(6) REFERENCES Client_master (Client_no),
...
You have a further problem as the check constraint you have against the order_no is CHECK(Order_no LIKE 'O%') but as mentioned the value you're putting in is 'C19001', which doesn't match the pattern. Presumably you meant the insert to be for 'O19001'; if not then the constraint is defined incorrectly. I actually hit that check constraint before the primary key constrain in 11gR2, so you may just have changed that while posting the question.
You can look in the user_constraints and user_cons_columns views to see what a constraint is doing, but you'll find it easier if you name your constraints instead of letting Oracle give them default names like SYS_C007155:
Specify a name for the constraint. If you omit this identifier, then Oracle Database generates a name with the form SYS_Cn. Oracle stores the name and the definition of the integrity constraint in the USER_, ALL_, and DBA_CONSTRAINTS data dictionary views (in the CONSTRAINT_NAME and SEARCH_CONDITION columns, respectively).
For example:
CREATE TABLE Client_master (
Client_no varchar(6),
Name varchar(15) NOT NULL,
City varchar(15),
Pincode number(8),
State varchar(15),
Bal_due Number(10,2),
CONSTRAINT Client_master_pk PRIMARY KEY (Client_no),
CONSTRAINT Client_master_chk_no CHECK(Client_no LIKE 'C%'));
INSERT INTO Client_master(Client_no,Name,City,Pincode,State,Bal_due)
VALUES('C00001','Ivan Bayross','Bombay','400054','Maharashtra',15000);
1 row inserted.
CREATE TABLE Sales_order (
Order_no varchar(6),
Order_date date,
Client_no varchar(6),
Dely_type char(1) DEFAULT 'f',
Billed_yn char(1),
Salesman_no varchar(6),
Dely_date date,
Order_status varchar(10),
CONSTRAINT Sales_order_pk PRIMARY KEY (Order_no),
CONSTRAINT Sales_order_fk_client FOREIGN KEY (Client_no)
REFERENCES Client_master (Client_no),
CONSTRAINT Sales_order_chk_no CHECK (Order_no LIKE 'O%'),
CONSTRAINT Sales_order_shk_status CHECK
(Order_status IN ('inprocess','backorder','cancelled')),
CONSTRAINT Sales_order_chk_dates CHECK(Dely_date>Order_date));
INSERT INTO Sales_order(Order_no, Order_date, Client_no, Dely_type, Billed_yn, Salesman_no, Dely_date, Order_status)
VALUES('O19001','12-jan-96','C00001','f','n','S0001','20-jan-96','inprocess');
1 row inserted.
If you do have a violation, e.g. with your original order_no value, you'd see a more useful message:
INSERT INTO Sales_order(Order_no, Order_date, Client_no, Dely_type, Billed_yn, Salesman_no, Dely_date, Order_status)
VALUES('C19001','12-jan-96','C00001','f','n','S0001','20-jan-96','inprocess');
ORA-02290: check constraint (YOUR_SCHEMA.SALES_ORDER_CHK_NO) violated
so you can have a better idea which constraint is violated, and what that means, without having to loo in the data dictionary. SALES_ORDER_CHK_NO is easier to interpret than SYS_C007155 Use names that make sense for you of course.
You can name inline constraints too:
CREATE TABLE Client_master (
Client_no varchar(6) CONSTRAINT Client_master_pk PRIMARY KEY,
...
CREATE TABLE Sales_order (
Order_no varchar(6) CONSTRAINT Sales_order_pk PRIMARY KEY,
Order_date date,
Client_no varchar(6) CONSTRAINT Sales_order_fk_client REFERENCES Client_master (Client_no),
...
but it might be clearer and easier to maintain with them all grouped together at the end.

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.

What is causing this sqlite foreign key mismatch?

I already checked out this question, and thought I had the answer - but then it didn't look right to me.
I have the following pared down example:
CREATE TABLE pipelines (
name VARCHAR NOT NULL,
owner VARCHAR NOT NULL,
description VARCHAR,
PRIMARY KEY (name, owner),
FOREIGN KEY(owner) REFERENCES user (id)
);
CREATE TABLE tasks (
id INTEGER NOT NULL,
title VARCHAR,
pipeline VARCHAR,
owner VARCHAR,
PRIMARY KEY (id),
FOREIGN KEY(pipeline) REFERENCES pipelines (name),
FOREIGN KEY(owner) REFERENCES pipelines (owner)
);
CREATE TABLE user (
id VARCHAR NOT NULL,
name VARCHAR,
password VARCHAR,
PRIMARY KEY (id)
);
pragma foreign_keys=on;
insert into user values ('wayne', '', '');
insert into pipelines values ('pipey', 'wayne', '');
insert into tasks values (1, 'hello', 'pipey', 'wayne');
When executing this code, it bails out:
$ sqlite3 foo.sq3 '.read mismatch.sql'
Error: near line 27: foreign key mismatch
Through the list in the question I cited:
the parent table (user) exists.
the parent columns (name, owner) exist
the parent columns are, in fact, the primary key (I thought that may have been it originally)
the child table references all of the primary key columns in the parent table
So what in the world could be causing this error?
The documentation says:
Usually, the parent key of a foreign key constraint is the primary key of the parent table. If they are not the primary key, then the parent key columns must be collectively subject to a UNIQUE constraint or have a UNIQUE index.
In the pipelines table, neither the name nor the owner columns are, by themselves, unique.
I guess you actually want to have a two-column foreign key in the tasks table:
FOREIGN KEY(pipeline, owner) REFERENCES pipelines(name, owner)

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...)

Resources