SQLite3, creating a relation one to many - sqlite

I'm creating an sqlite3 database with two tables. This is how I want it to be:
create table user(
id NOT NULL,
name varchar(40),
password varchar(40)
)
create table users_data(
id NOT NULL
note_name varchar(40),
note_description varchar(255),
)
and I want it to use one to many relation, so that one user has many note_name and note_description. How do I do this using SQlite?

You add the user id to the table users_data, because every users_data belongs to a user. That's it. Then let the database system help you guarantee data integrity with primary and foreign keys:
create table user(
id integer PRIMARY KEY,
name varchar(40),
password varchar(40)
);
create table users_data(
id integer PRIMARY KEY,
id_user integer NOT NULL,
note_name varchar(40),
note_description varchar(255),
FOREIGN KEY(id_user) REFERENCES user(id)
);
Read more on foreign keys here: https://www.sqlite.org/foreignkeys.html

Related

Sqlite3: Error deleting record: foreign key mismatch

I am trying to delete a record from table users.
Tried deleteing it with a DELETE-statement (DELETE FROM users WHERE user_id=10" as well as in my DB browser, but I get the above error, specifically it says: "Error deleting record: foreign key mismatch - "games" referencing "groups" (DELETE FROM "main"."users" WHERE rowid IN ('10');)".
Below my schema:
CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
name VARCHAR(255) NOT NULL,
hash VARCHAR(255) NOT NULL,
UNIQUE(name));
CREATE TABLE 'groups' (
'group_name' VARCHAR(255) NOT NULL,
'turn' INTEGER NOT NULL,
'user_id'INTEGER,
FOREIGN KEY ('user_id') REFERENCES 'users'('user_id')
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE TABLE games (
game_id INTEGER PRIMARY KEY,
active INTEGER,
turn INTEGER,
group_name VARCHAR(255) NOT NULL,
FOREIGN KEY (turn) REFERENCES groups(turn_id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (group_name) REFERENCES groups(group_name)
ON UPDATE CASCADE
ON DELETE NO ACTION
);
Why is this a problem? user_id is not even a foreign key in 'games'?? Thank you!
The problem in the end was my DB Browser for SQLite (3.11.2) whose GUI allows deletions but they don't actually work. When I tied again in the bash and closed and restarted the DB Browser, the rows were gone. Uninsightful but figured I'd post nonetheless in case anyone else comes across this.

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)

SQLite Multi-column Insert/Replace with Multiple Join

Sorry for the poor title. I have a query (below) that executes properly and creates an insertion just as I would desire. However, I want to make it smarter by only inserting when the exact combination of three columns. Essentially, the three column tuple is a primary key, but I'm working with the limitation of sqlite's single primary key.
Basic Context
I have 4 tables: Permissions, Roles, Users, Actions
Permissions connects Roles and Users to Actions. The Actions table has a list of available tasks that a User or a user with a Role can perform. So for example, if user_id = 1 can perform a list_folder action (action_id = 1), then the permissions table would have an entry: (id=1, action_id=1, user_id=1, role_id=NULL). Likewise, suppose an owner_role (role_id=1) might have permissions to perform a list_folder action (action_id=1), then the permissions entry might be: (id=2, action_id=1, user_id=NULL, role_id=1).
When I do an insert, I want to make sure that I do not already have that exact combination (e.g. action_id=1, user_id=NULL, role_id=1). And I'm not entirely sure how to write the sql so that I have this setup properly.
Here's my basic insert statement. I need to come up with an insert and a replace statement:
INSERT INTO permissions (
action_id
,role_id
)
SELECT DISTINCT
a.id as "action_id"
,r.id as "role_id"
FROM tmp_permissions tmp
LEFT OUTER JOIN actions a
ON tmp.action_name = a.name
LEFT OUTER JOIN roles r
ON tmp.roles_name = r.name
LEFT OUTER JOIN permissions p
ON p.role_id
Here are some creation sql statements for the tables:
CREATE TABLE permissions (
id INTEGER NOT NULL,
enabled INTEGER,
action_id INTEGER,
user_id INTEGER,
role_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(user_id) REFERENCES users (id),
FOREIGN KEY(action_id) REFERENCES actions (id),
FOREIGN KEY(role_id) REFERENCES roles (id)
);
CREATE TABLE actions (
id INTEGER NOT NULL,
enabled INTEGER,
name VARCHAR(50),
permission_ids INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(permission_ids) REFERENCES permissions (id)
);
CREATE TABLE roles (
id INTEGER NOT NULL,
enabled INTEGER,
name VARCHAR(50),
permission_ids INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(permission_ids) REFERENCES permissions (id)
);
CREATE TABLE users (
id INTEGER NOT NULL,
enabled INTEGER,
name VARCHAR(50),
permission_ids INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(permission_ids) REFERENCES permissions (id)
);
Here's a temp table I'm using to store the data in the table while I work with it:
CREATE TABLE tmp_permissions(
roles_name VARCHAR(50),
action_name VARCHAR(50)
);
Here's some data:
#role|action
admin|setup
admin|debug
admin|login
admin|view_user
manager|view_employee
manager|enroll_employee
manager|login
employee|schedule
employee|login
customer|guest_login
customer|change_credentials
guest|guest_login
Thanks in advance!
Add a UNIQUE constraint to the table:
CREATE TABLE permissions(
... ,
UNIQUE (action_id, user_id, role_id)
)
You can then use any of the conflict resolution algorithms to handle duplicates.

Drop Unique Key and generate new unique key

I have created one table in oracle data base my table script is
CREATE TABLE wsc_widget_bundle (
id VARCHAR (50),
widgetBundle BLOB NULL,
devicesoftwareclass VARCHAR(30) NOT NULL,
widgetProfileId VARCHAR (50) NOT NULL,
bundleHash BLOB NULL,
widgetLocale VARCHAR (6) NOT NULL ,
status INT,
primary key(id),
unique(widgetProfileId, devicesoftwareclass,status),
foreign key(widgetProfileId) references wsc_widget_profile(id)
);
When i create ddl for that is looks like
create table "DEV1"."WSC_WIDGET_BUNDLE"(
"ID" VARCHAR2(50) not null,
"WIDGETBUNDLE" BLOB,
"DEVICESOFTWARECLASS" VARCHAR2(30) not null,
"WIDGETPROFILEID" VARCHAR2(50) not null,
"BUNDLEHASH" BLOB,
"WIDGETLOCALE" VARCHAR2(6) not null,
"STATUS" NUMBER,
constraint "SYS_C00323290" primary key ("ID")
);
alter table "DEV1"."WSC_WIDGET_BUNDLE"
add constraint "SYS_C00323292"
foreign key ("WIDGETPROFILEID")
references "MTP440_DEV1"."WSC_WIDGET_PROFILE"("ID");
create unique index "MTP440_DEV1"."SYS_C00323290" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("ID");
create unique index "MTP440_DEV1"."SYS_C00323291" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("WIDGETPROFILEID","DEVICESOFTWARECLASS","STATUS");
create index "MTP440_DEV1"."TEST" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("DEVICESOFTWARECLASS","STATUS","WIDGETLOCALE","WIDGETPROFILEID");
Now i want to write alter script to alter unique key constrain of my table but as at creation of table I didn't mention the name of my unique key name it is given by system like SYS_C00323291
So how can I write alter script to drop that unique key whose name is not known to me and generation new one
You can find the name of the constraint by querying the user_constraints and user_cons_columns views.
Alter table x
drop constraint pk;
Alter table x
add constraint New_constraint_name PRIMARY KEY (colname);

Resources