MariaDB: ALTER TABLE syntax to add a FOREIGN KEY? - mariadb

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.

Related

10.4.24-MariaDB - Foreign key constraint is incorrectly formed

In person_addresses table i am getting error Foreign key constraint is incorrectly formed. My Version is 10.4.24-MariaDB
CREATE TABLE persons (
person_id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
email varchar(50) DEFAULT NULL,
phone int(11) DEFAULT NULL,
bio text DEFAULT NULL,
dob date DEFAULT NULL,
gender enum('Male','Female','Other') NOT NULL,
status tinyint(4) NOT NULL,
created_at timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (person_id),
UNIQUE KEY email (email),
UNIQUE KEY phone (phone)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE person_addresses (
person_id int(11) NOT NULL ,
address text NOT NULL,
created_at timestamp NOT NULL DEFAULT current_timestamp(),
UNIQUE KEY uc_person_address (person_id,address),
CONSTRAINT fk_person FOREIGN KEY (person_id) REFERENCES persons(person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
More Detailed Error
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2023-01-11 12:41:52 0x421c Error in foreign key constraint of table `test`.`person_addresses`:
There is no index in table ```test``.``person_addresses``` where the columns appear
as the first columns. Constraint:
FOREIGN KEY (person_id) REFERENCES persons (person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
Please refer to https://mariadb.com/kb/en/library/foreign-keys/ for correct foreign key definition.Create table `test`.`person_addresses` with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' FOREIGN KEY (person_id) REFERENCES persons (person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4'.
I think I found a matching bug report in MariaDB: https://jira.mariadb.org/browse/MDEV-29717
The issue is that if the index required for the foreign key is very large, the index is created automatically. But this fails if that index is larger than the index size limit for the storage engine (this should be 3072 bytes in the version of MariaDB you are using, because it defaults to DYNAMIC row format with innodb_large_prefix=on). The text type in your index is too large to be indexed without defining an index prefix. But foreign keys can't use indexes defined with index prefixes.
Unfortunately, because foreign keys are implemented deep in the storage engine, there is little opportunity for a more informative error message to be revealed. This is a problem with the implementation of pluggable storage engines.
The solution in your case should be to change the address column type. It cannot be text, it can only be a varchar that is not too long for the index prefix length limit.
For example, I tested with MariaDB 10.4. https://dbfiddle.uk/5jTX8iFt It fails if address is text, and it works fine if address is varchar(255). I did not test other lengths, I'll leave that to you.
I doubt you need text for an address anyway. Does anyone have an address that requires 64KB?

MariaDB 10.1 Truncate table cascade syntax error

When i try to execute the following sql statemant MariaDB give an error:
SQL: TRUNCATE $table CASCADE;
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CASCADE' at line 1 (SQL: TRUNCATE wortmann_products CASCADE;)
is cascade removed in MariaDB or is there something wrong whit the sql statement?
If you are looking to cascade out deletes and updates then the definition has to be stored when the table is created or altered, and will apply to the keys (or FK's in associated tables) allowing child records to be deleted in associated table when parent record is deleted. There are plenty of resources on this, I have listed one here: https://mariadb.com/kb/en/the-mariadb-library/foreign-keys/ - Taken from this resource is the example below:
CREATE TABLE author (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL
) ENGINE = InnoDB;
CREATE TABLE book (
id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
author_id SMALLINT UNSIGNED NOT NULL,
CONSTRAINT `fk_book_author`
FOREIGN KEY (author_id) REFERENCES author (id)
ON DELETE CASCADE
ON UPDATE RESTRICT
) ENGINE = InnoDB;

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.

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.

Creating foreign key on same table 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)

Resources