SQLite composite key for a table between two tables - sqlite

I am trying to Connect Three tables. Two of them have Primary Keys which the Third is supposed to link to. I need this inbetween as it is linked to a fourth (but this Works fine). The code I have written is as follows:
CREATE TABLE CUSTOMERS(
CUSTOMER_ID INT(10) NOT NULL,
SURNAME CHAR(50) NOT NULL,
NAME CHAR(50) NOT NULL,
PRIMARY KEY (CUSTOMER_ID)
);
CREATE TABLE WORKSHOP(
WORKSHOP_ID INT(10) NOT NULL,
NAME CHAR(100) NOT NULL,
CHAIN_NAME CHAR(100),
CHAIN_ID INT(10),
CONTRACT_WORKSHOP CHAR(5) NOT NULL,
PRIMARY KEY (WORKSHOP_ID, CHAIN_ID)
);
CREATE TABLE CAR_DAMAGE(
DAMAGE_ID INT(10) NOT NULL,
CUSTOMER_ID INT(10) NOT NULL,
DATE INT(20) NOT NULL,
PLACE CHAR(128) NOT NULL,
WORKSHOP_ID INT(10) NOT NULL,
PRIMARY KEY (DAMAGE_ID, CUSTOMER_ID, WORKSHOP_ID, DATE, PLACE),
FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMERS (CUSTOMER_ID),
FOREIGN KEY (WORKSHOP_ID) REFERENCES WORKSHOP (WORKSHOP_ID)
);
INSERT INTO CUSTOMERS VALUES (1, "OLSEN", "TROND");
INSERT INTO CUSTOMERS VALUES (2, "JOHNSEN", "FELIX");
INSERT INTO CUSTOMERS VALUES (3, "SVINDAL", "AKSEL");
INSERT INTO CUSTOMERS VALUES (4, "BJORGEN", "MARIT");
INSERT INTO CUSTOMERS VALUES (5, "SVENDSON", "LISA");
INSERT INTO WORKSHOP VALUES (1, "BERTEL", "MOLLER", 1, "YES");
INSERT INTO WORKSHOP VALUES (2, "OLOF", "OLOF AUTO", 3, "NO");
INSERT INTO WORKSHOP VALUES (3, "J-AUTO", "MOLLER", 1, "YES");
INSERT INTO WORKSHOP VALUES (4, "SPEED", "BIRGER N. HAUG", 2, "YES");
INSERT INTO WORKSHOP VALUES (5, "RELAX AUTO", "MOLLER", 1, "YES");
INSERT INTO CAR_DAMAGE VALUES (1, 1, 10102008, "HELLERUD", 1);
INSERT INTO CAR_DAMAGE VALUES (2, 2, 14032015, "JAR", 2);
INSERT INTO CAR_DAMAGE VALUES (3, 3, 24052016, "LOMMEDALEN", 3);
INSERT INTO CAR_DAMAGE VALUES (4, 4, 31102017, "FLAKTVEIT", 4);
INSERT INTO CAR_DAMAGE VALUES (5, 5, 08062016, "STOCKHOLM", 5);
However, the problem occur as I get the error "foriegn key mismatch - CAR_DAMAGE referencing WORKSHOP.
I am using SQLite as I am forced to use it, given by my University.

Table WORKSHOP has a composite primary key (WORKSHOP_ID, CHAIN_ID). Any foreign key referencing that table must be a composite foreign key, consisting of the same two fields. Hence, you would need to add CHAIN_ID to table WORKSHOP and change your foreign key declaration to something like:
FOREIGN KEY (WORKSHOP_ID, CHAIN_ID) REFERENCES WORKSHOP (WORKSHOP_ID, CHAIN_ID)
[More generally, your primary keys seem, based on the information given, more complex than they need to be: why not just have WORKSHOP_ID as PK of WORKSHOP and DAMAGE_ID as PK of CAR_DAMAGE? But maybe you have good reasons.]

Thank you. This Method worked. Hence, when I proceeded, a New problem occured. The table CAR_DAMAGE is linked to a fourth table (Called DAMAGE_INFORMATION), With the code:
CREATE TABLE DAMAGE_INFORMATION(
DAMAGE_ID INT(10) NOT NULL,
DAMAGE_TYPE CHAR(100) NOT NULL,
DAMAGE_SIZE CHAR(50) NOT NULL,
SPEND INT(10) NOT NULL,
FOREIGN KEY (DAMAGE_ID) REFERENCES CAR_DAMAGE (DAMAGE_ID)
);
And I receive the same error as earlier, i.e. Foreign key mismatch "DAMAGE_INFORMATION" referencing "CAR_DAMAGE".
Is it not allowed to make a combination of 3 tables to 1, With different primary keys? The primary key of CAR_DAMAGE is:
PRIMARY KEY (DAMAGE_KEY, CUSTOMER_ID, WORKSHOP_ID)

Related

How to make something similar as an if statement in Sqlite?

This is my SQLite file:
CREATE TABLE IF NOT EXISTS COTXE ( /*Table to create the cars*/
matricula VARCHAR(7) NOT NULL PRIMARY KEY, /*CarPlate*/
marca INTEGER, /*Brand*/
color INTEGER /*Color*/
);
CREATE TABLE IF NOT EXISTS PLASA ( /*Table to crate all the sites of the parking*/
pos INTEGER NOT NULL PRIMARY KEY, /*Number of the parkingsite*/
superficie INTEGER, /*How many m² it has*/
ocupada BOOL /*If its empty or not (0 = empty)*/
);
CREATE TABLE IF NOT EXISTS APARCAR ( /*Table to park a car in a site of the parking*/
pos_plaça INTEGER, /*Number of the parking site*/
matricula VARCHAR(7), /*Carplate*/
data_in DEFAULT CURRENT_TIMESTAMP, /*Date when it enters the parking*/
data_out DEFAULT NULL, /*Date when it leaves the parking*/
PRIMARY KEY (matricula, data_in),
FOREIGN KEY (pos_plaça) REFERENCES PLASA(pos),
FOREIGN KEY (matricula) REFERENCES COTXE(matricula)
);
/*Inserts to add cars and parking sites*/
INSERT INTO COTXE VALUES ('9882JPX', 0, 0);
INSERT INTO COTXE VALUES ('1111DDD', 4, 9);
INSERT INTO COTXE VALUES ('2222SSS', 8, 8);
INSERT INTO COTXE VALUES ('3333FFF', 3, 5);
INSERT INTO PLASA (superficie, ocupada) VALUES (50, 0);
INSERT INTO PLASA (superficie, ocupada) VALUES (34, 0);
INSERT INTO PLASA (superficie, ocupada) VALUES (24, 0);
I've got a little problem and its when i try to add, for example the first car two times in the same parking site without leaving in any of those it adds again the same car in the same parking site that should be impossible, i drop here an example:
sqlite> INSERT INTO APARCAR (pos_plaça, matricula) VALUES (1, '9882JPX');
sqlite> UPDATE PLASA SET ocupada = 1 WHERE pos = 1;
sqlite> INSERT INTO APARCAR (pos_plaça, matricula) VALUES (1, '9882JPX');
sqlite> SELECT * FROM APARCAR;
pos_plaça matricula data_in data_out
---------- ---------- ------------------- ----------
1 9882JPX 2022-03-17 17:41:24
1 9882JPX 2022-03-17 17:41:26
So i'm asking you guys if any of you know how to condition the INSERT INTO and before adding the car in that parking site, check if its full.
Sorry for my bad english and explanations.

create virtual column in mariadb with case statement fails

I am trying to create a table in MariaDB with a virtual column, defined by a case statement
This is what I have
create table Foto (
ID int AUTO_INCREMENT not null primary key,
LigPlaatsCode varchar(10) not null,
FotoTypeID int not null check (FotoType in (0, 1, 2, 3)),
Foto varchar(1000) not null,
FotoType varchar(50) as
case FotoTypeID
when 0 then 'Bidprent'
when 1 then 'Krantartikel'
when 2 then 'Persoon'
else 'Graf'
end, `
constraint FK_Foto_LigPlaats foreign key (LigPlaatsCode) references LigPlaats (LigPlaatsCode)
)
however it always gives me this error
#42000You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
near 'case FotoTypeID
when 0 then 'Bidprent'
when 1 then 'Krantar' at line 7
When I google on how to create virtual column and case, the links I found seem to suggest I got it right, but obviously I dont. So I am missing something.
What is wrong with this create table statement ?
EDIT
my version is 10.3.21-MariaDB
Generated column requires parantehese around case expression:
create table Foto (
ID int AUTO_INCREMENT not null primary key,
LigPlaatsCode varchar(10) not null,
FotoTypeID int not null ,
Foto varchar(1000) not null,
FotoType varchar(50) as
(case FotoTypeID
when 0 then 'Bidprent'
when 1 then 'Krantartikel'
when 2 then 'Persoon'
else 'Graf'
end), -- brackets around
-- constraint as separate entry because it is referencing FotoType
constraint fototypecheck check (FotoType in (0, 1, 2, 3))
);
db<>fiddle demo
This line does not make sense as FotoType is text:
FotoTypeID int not null check (FotoType in (0, 1, 2, 3)),
-- probably it should be
FotoTypeID int not null check (FotoTypeID in (0, 1, 2, 3)),

How to move column from referenced table to referrer table using only SQLite language dialect?

I have following table structure in SQLite database:
CREATE TABLE A (id integer primary key, name text, room Integer);
CREATE TABLE B (id integer primary key, idA integer not null, code blob, FOREIGN KEY(idA) REFERENCES A(id));
For each record in A there are 1 to n records in B that refers it. Desired table structure is:
CREATE TABLE A (id integer primary key, name text);
CREATE TABLE B (id integer primary key, idA integer not null, code blob, room Integer, FOREIGN KEY(idA) REFERENCES A(id));
So, I would like to transer room column from A to B without data loss: recreate table A without room column, delete duplicates from A, add room column to B, set it depends on what values were in referenced A records room columns (original A table) and reassign idA for B records.
Is it possible using only SQLite and if it is, how to do this, using only SQLite?
Thank you!
have a look at http://sqlfiddle.com/#!5/e26e2/1 .
creating the databases :
CREATE TABLE A (id integer primary key, name text, room Integer);
CREATE TABLE B (id integer primary key, idA integer not null, code blob, FOREIGN KEY(idA) REFERENCES A(id));
Fill in some test data :
insert into A (id, name, room) values (1, "azerty", 123) ;
insert into A (id, name, room) values (2, "querty", 456) ;
insert into B (id, idA, code) values (10, 1, "code 1") ;
insert into B (id, idA, code) values (15, 1, "code 1b") ;
insert into B (id, idA, code) values (20, 1, "code 1c") ;
insert into B (id, idA, code) values (25, 2, "code 2") ;
insert into B (id, idA, code) values (30, 3, "code 3") ;
copy the wrong table layouts to tables we will later drop :
alter table B rename to old_B ;
alter table A rename to old_A ;
Create tables according the correct layout :
CREATE TABLE A (id integer primary key, name text);
CREATE TABLE B (id integer primary key, idA integer not null, code blob, room Integer, FOREIGN KEY(idA) REFERENCES A(id));
Copy selected data from old_A into A :
INSERT OR REPLACE INTO A ( id, name)
SELECT id, name FROM old_A ;
fill B with an inner join to "line up" room with correct idA :
INSERT OR REPLACE INTO B ( id, idA, code, room)
SELECT old_B.*, old_A.room FROM old_B INNER JOIN old_A ON old_B.idA = old_A.id ;
drop the old tables
DROP TABLE old_A ;
DROP TABLE old_B ;

How to build unique constraints in SQLite

I been trying to follow this example on how to build constraints in SQLite.
I created a table:
CREATE TABLE `users` (
`user_id` INTEGER NOT NULL DEFAULT 1 PRIMARY KEY AUTOINCREMENT,
`row_id` INTEGER NOT NULL,
unique (user_id, row_id)
)
Than I been trying to make an insertions:
insert into users(user_id, row_id) values(1, 13)
insert into users(user_id, row_id) values(2, 13)
On the second insertion query it failed with the next message:
UNIQUE constraint failed: users.user_id: insert into users(user_id,
row_id) values(2, 13)
I want to allow the next rows:
1,13
2,13
1,5
And disallow those
1,13
1,13
PRIMARY KEY is by design UNIQUE and NOT NULL so user_id has to be UNIQUE.
Then you have UNIQUE constraint on columns user_id and row_id.
You could use composed PRIMARY KEY:
CREATE TABLE `users` (
`user_id` INTEGER NOT NULL,
`row_id` INTEGER NOT NULL,
PRIMARY KEY (user_id, row_id)
);
INSERT INTO users(user_id, row_id) VALUES(1, 13);
INSERT INTO users(user_id, row_id) VALUES(2, 13);
INSERT INTO users(user_id, row_id) VALUES(1, 5);
INSERT INTO users(user_id, row_id) VALUES(1, 13);
-- Error: UNIQUE constraint failed: users.user_id, users.row_id
SqlFiddleDemo
Primary Key is causing the issue, once a column is defined as primary it cannot be duplicated. Please try dropping the Primary Key.
CREATE TABLE `users` (
`user_id` INTEGER AUTO INCREMENT NOT NULL DEFAULT 1,
`row_id` INTEGER NOT NULL,
unique (user_id, row_id)
)

sqlite3: how to select same row twice when there is a match?

Create SOF.SQL
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US');
INSERT INTO "android_metadata" VALUES ('en_US');
CREATE TABLE main.t_def (
_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
word TEXT(20) not null,
word_def TEXT(20) not null
);
insert into t_def (word, word_def) values ('ball','spherical object');
insert into t_def (word, word_def) values ('cat','feline');
insert into t_def (word, word_def) values ('dog','common housekept');
CREATE TABLE main.t_a (
_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
corr_answer TEXT(20) not null,
user_answer TEXT(20) not null,
is_correct INTEGER not null
);
insert into t_a (user_answer, corr_answer, is_correct) values ('ball','cat',0);
insert into t_a (user_answer, corr_answer, is_correct) values ('dog','dog',1);
.exit
Then run:
sqlite3 foo.db < SOF.SQL
I want a result set that is:
ball|spherical object|cat|feline|0
This is the closest I have gotten:
select t_def.word, t_def.word_def from t_def, t_a where t_a.is_correct=0 and t_a.corr_answer=t_def.word;
To get values from two rows, you need two instances of the table:
SELECT t_a.user_answer,
user_def.word_def AS user_word_def,
t_a.corr_answer,
corr_def.word_def AS corr_word_def,
t_a.is_correct
FROM t_a
JOIN t_def AS user_def ON t_a.user_answer = user_def.word
JOIN t_def AS corr_def ON t_a.corr_answer = corr_def.word
WHERE NOT t_a.is_correct

Resources