Creating foreign key on same table SQLite - sqlite

Recently I started using SQLite (as required for my study) and I came accross a couple of restrictions of SQLite and I was wondering: can't SQLite create foreign keys on the same table? E.g. this is my code:
CREATE TABLE Categories
(
name varchar(20),
parent_category varchar(20) NULL,
PRIMARY KEY(name),
FOREIGN KEY parent_category_fk(parent_category) REFERENCES Categories(name)
)
But it gives me an error for the foreign key when I try to execute the SQL in SQLiteStudio.
Does anyone know why this isn't working?

The problem is that you have the wrong syntax for the FK clause. It should be:
FOREIGN KEY (parent_category) REFERENCES Categories(name)
If you want to name the FK constraint, you do that with a prefix of the CONSTRAINT keyword, like this:
CONSTRAINT parent_category_fk FOREIGN KEY (parent_category) REFERENCES Categories(name)

Related

How to get the names of foreign key constraints in SQLite?

Does SQLite indeed have a limitation that it is not possible to retrieve the name of a foreign key? I am asking because I couldn't find this limitation mentioned anywhere in their documentation.
For example, I run the following script:
CREATE TABLE
users (
id INTEGER NOT NULL PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL
) ;
CREATE TABLE
orders (
id INTEGER NOT NULL PRIMARY KEY,
user_id INTEGER NOT NULL,
CONSTRAINT fk_users FOREIGN KEY (user_id) REFERENCES users(id)
) ;
Now I would like to check that the key "fk_users" was created indeed, so I run the following PRAGMA:
PRAGMA foreign_key_list(orders);
I would expect to see the name of my foreign key in the first column, but I am seeing some "0" value instead. Moreover, if I create multiple foreign keys with custom names, they are all called either "0" or "1".
Is this indeed a limitation of SQLite, or am I missing something?
There is no mechanism to extract the constraint name.
The table sqlite_master stores a CREATE command in the column "sql". You could query that command and do some parsing to extract the name of the foreign key. An example for a combined foreign key that works for me:
SELECT sql FROM sqlite_master WHERE name = 'song'
yields
CREATE TABLE "song" (
"songid" INTEGER,
"songartist" TEXT,
"songalbum" TEXT,
"songname" TEXT,
CONSTRAINT "fk__song_album" FOREIGN KEY ("songartist", "songalbum") REFERENCES "album" ("albumartist", "albumname")
)
and contains the name "fk__song_album" of the foreign key.
If one alters the foreign key with a query, the content of the sql column is modified/updated:
The text in the sqlite_master.sql column is a copy of the original CREATE statement text that created the object, except normalized as described above and as modified by subsequent ALTER TABLE statements. The sqlite_master.sql is NULL for the internal indexes that are automatically created by UNIQUE or PRIMARY KEY constraints.
https://www.sqlite.org/fileformat2.html
Extra tip:
In order to see the foreign key information in Navicat (Lite) ... right click on a table and choose "Design table". Then select the foreign keys tab.

MariaDB: ALTER TABLE syntax to add a FOREIGN KEY?

what'S wrong with the following statement?
ALTER TABLE submittedForecast
ADD CONSTRAINT FOREIGN KEY (data) REFERENCES blobs (id);
The error message I am getting is
Can't create table `fcdemo`.`#sql-664_b` (errno: 150 "Foreign key constraint is incorrectly formed")
This works for me on MariaDB 10.1.8:
CREATE TABLE `submittedforecast` (
`id` INT(11) NOT NULL,
`data` INT(11) NOT NULL,
PRIMARY KEY (`id`),
INDEX `data` (`data`)
) ENGINE=InnoDB;
CREATE TABLE `blobs` (
`id` INT(11) NOT NULL,
`content` BLOB NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
ALTER TABLE submittedForecast
ADD CONSTRAINT FOREIGN KEY (data) REFERENCES blobs (id);
Can you give your MariaDB version number and a complete example including the CREATE TABLE statements for submittedForecast and blobs?
No idea if you already solved this but make sure both engines and collations match between tables (e.g: latin1 to latin1 and InnoDB to InnoDB).
I was having the same issue and by switching these I managed to get it working.
I was getting the same issue and after looking at my table structure, found out that my child table's foreign key clause was not referencing the primary key of parent table. Once i changed it to reference to primary key of parent table, the error was gone.
I had the same error and is actually pretty easy to solve, you have name the constraint, something like this should do:
ALTER TABLE submittedForecast ADD CONSTRAINT `fk_submittedForecast`
FOREIGN KEY (data) REFERENCES blobs (id)
If you would like more cohesion also add at the end of the query
ON DELETE CASCADE ON UPDATE RESTRICT
This could also be a different fields error so check if the table key and the foreign key are of the same type and have the same atributes.
I had the same problem, too. When checking the definition of the fields, I noticed that one field was defined as INT and the other as BIGINT. After changing the BIGINT type to INT, I was able to create my foreign key.

invalid alter table option while modify foreign key

I want to modify the update option of one foreign key.
For this I executed this command:
alter table testusers.ORDERS
DROP CONSTRAINT ORDER_FK_2,
ADD CONSTRAINT ORDER_FK_2 FOREIGN KEY(FK_PRODUCER_ID) REFERENCES testuser.PRODUCER (producer_id)
ON UPDATE CASCADE ON DELETE CASCADE;
If I execute this, there is the following error:
SQL-Fehler: ORA-01735: Ungültige Option ALTER TABLE
01735. 00000 - "invalid ALTER TABLE option"
There is no comma separated list for the alter table according to documentation syntax diagram http://docs.oracle.com/cd/B28359_01/server.111/b28286/clauses002.htm#CJAEDFIB
create table orders(order_id number, fk_producer_id number, CONSTRAINT order_pk PRIMARY KEY (order_id));
create table producer(producer_id number, CONSTRAINT producer_pk PRIMARY KEY (producer_id));
alter table orders
ADD CONSTRAINT ORDER_FK_2 FOREIGN KEY( FK_PRODUCER_ID)
REFERENCES PRODUCER (producer_id) ;
alter table orders
DROP CONSTRAINT ORDER_FK_2;
alter table orders
ADD CONSTRAINT ORDER_FK_2 FOREIGN KEY( FK_PRODUCER_ID)
REFERENCES PRODUCER (producer_id) ;
Ahm, yes, and I could not find any ON UPDATE CASCADE syntax either. But I am sure you can work it out now. Otherwise drop a little comment or post a new question.

Does WebSQL support primary keys?

I'm creating a WebSQL table in Chrome with the following statement:
'CREATE TABLE IF NOT EXISTS recs(id, fname,lname,email,country,comments, synced integer,PRIMARY KEY(id))'
Inserting records does not appear to be creating primary keys. How should one go about creating unique keys in webSQL?
Use the unique keyword and check for the constraint error to verify.
'CREATE TABLE IF NOT EXISTS recs (id unique, fname, lname)'

Implement/use foreign keys in SQLite?

How can I implement a foreign key in SQLite? I was thinking something like this:
CREATE TABLE job (_id INTEGER PRIMARY KEY AUTOINCREMENT, employer_id INTEGER, ...);
CREATE TABLE employer(_id INTEGER, employer_name TEXT NOT NULL, ...);
Where employer_id is the _id from the table employer. Would this work? Is there another fast, maybe less prone to error way? Maybe with triggers?
Maybe I don't understand the question, but if it's the constraint you want, just do this:
ALTER TABLE Job
ADD FOREIGN KEY (employer_id)
REFERENCES Employer(_id)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
See SQLite (3.6.19) Foreign Key Support
(Earlier version of SQLite do not support enforced FK relationships.)

Resources