Im trying to link my tables now with foreign keys but with the following tables I have a few problems.
My tables
table users
- user_id INT(8) AUTO_INCREMENT //this is completly underlined
- username VARCHAR(150)
- password VARCHAR(50)
- auth_lvl VARCHAR(10) //this is "half underlined"
- ...
PRIMARY KEY: user_id
-------------------------------------------------
table groups
- group_id INT(11) AUTO_INCREMENT
- group_name VARCHAR(30)
- group_desc VARCHAR(60)
PRIMARY KEY: group_id
-------------------------------------------------
table users_groups
- user_id INT(10)
- group_id INT(10)
PRIMARY KEY: user_id, group_id (command was: PRIMARY KEY(user_id, group_id)
INDEX: group_id (these are seperated)
INDEX: user_id (these are seperated)
Now I wanted to create a foreign key with this:
ALTER TABLE `users_groups`
ADD FOREIGN KEY (`user_id`)
REFERENCES `DB`.`users` (`user_id`)
ON DELETE CASCADE
ON UPDATE RESTRICT
The error was:
#1452 - Cannot add or update a child row: a foreign key constraint fails
(`db`.<result 2 when explaining filename '#sql-censored'>, CONSTRAINT
`#sql-censored` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`)
ON DELETE CASCADE)
My second foreign key I wanted to create:
ALTER TABLE `users_groups`
ADD FOREIGN KEY (`group_id`)
REFERENCES `DB`.`groups` (`group_id`)
ON DELETE CASCADE
ON UPDATE RESTRICT
The error was:
Error creating foreign key on group_id (check data types)
What is the problem with these? I cannot find the fault :/
The first one seems to indicate you have data in the table that does not satisfy the foreign key constraint.
The second one may be caused by the different data types INT(10) vs. INT(11).
Probably specifying INTEGER for all columns would solve this.
Solution
I had some rows in users_groups where the user_id was an id of an user which isn't in the users table anymore.
After I deleted these values which aren't exisiting in users anymore, all worked!
Related
I cannot seem to be able to delete primary keys in a table.
All references (FKs) have been removed but it still doesn't let me delete it.
What I'm trying to do is: delete old primary keys to add a new one - but keep the old columns and data (just remove the PK attribute).
What is wrong ?
Table:
CREATE TABLE `employee` (
`User` int(10) unsigned NOT NULL,
`Company` int(10) unsigned NOT NULL,
--unrelated boolean fields
PRIMARY KEY (`User`,`Company`),
KEY `FK_Employee_Company_idx` (`Company`),
CONSTRAINT `FK_Employee_Company` FOREIGN KEY (`Company`) REFERENCES `company` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_Employee_User` FOREIGN KEY (`User`) REFERENCES `user` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Trying to delete:
alter table Employee
drop primary key;
Issue:
Error 1025: Error on rename of '.\DB_NAME#sql-3640_4' to '.\DB_NAME\employee' (errno: 150 "Foreign key constraint is incorrectly formed") SQL Statement: ALTER TABLE DB_NAME.employee DROP PRIMARY KEY
Nothing references this table anymore. I also checked via statements which select from information_schema.key_column_usage but yields no results.
Wasted the last hours on Google but can't seem to figure it out.
And if that would work, adding a new column:
alter table Employee
add column ID int unsigned not null auto_increment primary key;
The index is still needed for the existing FK constraints.
Adding the following index (first) should satisfy that requirement:
CREATE INDEX xxx ON employee (User, Company);
Test case
I am following along with a UDEMY course about SQL. The instructor is working in postgresql. I am working in MySQL workbench. Our corporate development is in MySQL 5.6 on the AWS platform. So I want to learn in MySQL.
There is a lecture about "creating tables" and using constraint and foreign key commands to link the primary keys in two different tables. This is something I want to do with my data, so the challenge is relevant. The instructor's code does not compile for me. I get "error code 1215. Cannot add foreign key constraint".
I have read here that the variables must have the exact same definition. So I changed the instructor's tables from "serial" to int. I am still getting the error. I have tried simplifying the code. I'm still not getting anywhere. Can anybody help me understand why it is not executing?
create table if not exists accounts(
user_id INT auto_increment not null,
username varchar(50) unique not null,
password varchar(50) not null,
email varchar(350) unique not null,
created_on timestamp not null,
last_login timestamp,
primary key (user_id)
);
create table if not exists role(
role_id INT auto_increment not null,
role_name varchar(250) unique not null,
PRIMARY KEY (role_id)
);
create table accounts_role(
user_id INT,
role_id INT,
grant_date timestamp,
primary key (user_id, role_id),
constraint accounts_role_role_id_fkey foreign key (role_id)
references role(role_id) match simple
on update no action
on delete no action,
constraint accounts_role_user_id_fkey foreign key (user_id)
references account (user_id) MATCH SIMPLE
on update no action
on delete no action
);
good grief.
Thanks Caius, i was implementing your suggestion and I found the answer to my problem.
i realized that my table is named "accounts" and i was creating a constraint on "account" ...
create table accounts_role(
user_id INT,
role_id INT,
grant_date timestamp,
primary key (user_id, role_id),
constraint accounts_role_role_id_fkey foreign key (role_id)
references role(role_id) match simple
on update no action
on delete no action,
constraint accounts_role_user_id_fkey foreign key (user_id)
references accounts(user_id) MATCH SIMPLE
on update no action
on delete no action
);
I found this thread similar to my query:
How to Link Foreign Key with Different Name
But unfortunately the answer to the question above doesn't resolve my problem as on my example tables, it doesn't create any primary key, all foreign keys only.
Here is the query for the table structure:
CREATE TABLE ref_data(
user_id INT(11) NOT NULL,
ref_id INT(11) NOT NULL,
ref_name VARCHAR(30) NOT NULL,
ref_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT FK_user_id FOREIGN KEY(user_id) REFERENCES client (user_id),
CONSTRAINT FK_ref_id FOREIGN KEY(ref_id) REFERENCES client (user_id),
CONSTRAINT FK_ref_name FOREIGN KEY(ref_name) REFERENCES client (firstname)
);
I get the following error:
errno: 150 "Foreign key constraint is incorrectly formed"
Here I am using user_id twice, with the first as user_id and second as ref_id. I'm also using firstname as ref_name.
This is the client table:
CREATE TABLE client (
`user_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(30) NOT NULL UNIQUE KEY,
`email` VARCHAR(50) NOT NULL UNIQUE KEY,
`firstname` VARCHAR(30) NOT NULL,
`lastname` VARCHAR(30) NOT NULL,
`password` CHAR(128) NOT NULL
);
Ok, when trying to create the ref_data table, after the foreign key error, I see this:
LATEST FOREIGN KEY ERROR
------------------------ 2017-07-13 01:07:00 37ec Error in foreign key constraint of table ref_data:
FOREIGN KEY(ref_name) REFERENCES client (firstname) ):
Cannot find an index in the
referenced table where the referenced columns appear as the first
columns, or column types in the table and the referenced table do not
match for constraint. Note that the internal storage type of ENUM and
SET changed in tables created with >= InnoDB-4.1.12, and such columns
in old tables cannot be referenced by such columns in new tables. See
http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition. Create table 'test.ref_data'
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(ref_name) REFERENCES client (firstname) )'.
What that error is basically saying: (in the bold text)
There is no index on 'firstname' for the 'client' table (the portion after the REFERENCES clause of the FOREIGN KEY
But it's a simple fix. Run this SQL on the client table:
ALTER TABLE `client` ADD INDEX(`firstname`);
... and then run the ref_data table SQL again.
I'm trying to create a the following table using MySQL:
CREATE TABLE registrations (
eventNumber CHAR(3) UNIQUE NOT NULL
CHECK (EXISTS (SELECT eventNumber FROM events)),
employeeNumber CHAR(5) UNIQUE NOT NULL
CHECK (EXISTS (SELECT employeeNumber FROM employees)),
PRIMARY KEY(eventNumber , employeeNumber ),
FOREIGN KEY (eventNumber) REFERENCES eventNumber (employees)
ON UPDATE RESTRICT
ON DELETE RESTRICT,
FOREIGN KEY (employeeNumber ) REFERENCES employeeNumber(employees)
ON UPDATE RESTRICT
ON DELETE RESTRICT
) ENGINE=InnoDB;
However, I get a can't create table error (1005) when I run the command. What might be going wrong here?
For reference, I got the REFERENCES statement wrong.
It should in fact read:
REFERENCES <table name>(<attribute name>)
I have the following script to create a table in MySQL version 5.1 which is to refer to 3 other tables. All 3 tables have been created using InnoDB, and all 3 tables have the ID column defined as INT.
I have created other tables successfully which reference ACCOUNT and PERSON, however, this is the first table which references ADDRESS, so I've included the definition for that table, as run, below as well.
The error which I'm getting is ERROR 1005 (HY000) with errno 150, which I understand to be relating to foreign key creation.
The script which fails is (extra columns removed for simplicity):
CREATE TABLE WORK_ORDER (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ACCOUNT_ID INT NOT NULL,
CUSTOMER_ID INT NOT NULL,
SALES_ID INT,
TRADES_ID INT,
LOCATION_ID INT NOT NULL,
INDEX CUST_INDEX(CUSTOMER_ID),
INDEX SALES_INDEX(SALES_ID),
INDEX TRADES_INDEX(TRADES_ID),
INDEX ACCOUNT_INDEX(ACCOUNT_ID),
INDEX LOCATION_INDEX(LOCATION_ID),
FOREIGN KEY (CUSTOMER_ID) REFERENCES PERSON(ID) ON DELETE CASCADE,
FOREIGN KEY (SALES_ID) REFERENCES PERSON(ID) ON DELETE SET NULL,
FOREIGN KEY (TRADES_ID) REFERENCES PERSON(ID) ON DELETE SET NULL,
FOREIGN KEY (ACCOUNT_ID) REFERENCES ACCOUNT(ID) ON DELETE CASCADE,
FOREIGN KEY (LOCATION_ID) REFERENCES ADDRESS(ID) ON DELETE SET NULL
) ENGINE=InnoDB;
The SQL statement used to create the ADDRESS table is below (extra columns removed for simplicity).
CREATE TABLE ADDRESS (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
PERSON_ID INT NOT NULL,
ACCOUNT_ID INT NOT NULL,
ADDRESS_L1 VARCHAR(50),
ADDRESS_L2 VARCHAR(50),
CITY VARCHAR(25),
PROVINCE VARCHAR(20),
POSTAL_CODE VARCHAR(6),
COUNTRY VARCHAR(25),
INDEX CUST_INDEX(PERSON_ID),
INDEX ACCOUNT_INDEX(ACCOUNT_ID),
FOREIGN KEY (ACCOUNT_ID) REFERENCES ACCOUNT(ID) ON DELETE CASCADE,
FOREIGN KEY (PERSON_ID) REFERENCES PERSON(ID) ON DELETE CASCADE
) ENGINE=InnoDB;
I've browsed through several questions here dealing with similar issues, but most seem to be duplicate definitions and non-matching field types, as well as some not using InnoDB for one or the other of the tables. However, none of these seem to be the problem. Any ideas?
You can always issue a 'SHOW ENGINE INNODB STATUS' command. Buried in the output will be a "LATEST FOREIGN KEY ERROR" section, which will have more details on exactly what caused the '150' error:
mysql> create table a (x int not null) type=innodb;
Query OK, 0 rows affected, 1 warning (0.02 sec)
mysql> create table b (y int not null, foreign key (y) references a (x) on delete set null) type=innodb;
ERROR 1005 (HY000): Can't create table './test/b.frm' (errno: 150)
mysql> show engine innodb status;
[..... snip snip snip ...]
------------------------
LATEST FOREIGN KEY ERROR
------------------------
091129 16:32:41 Error in foreign key constraint of table test/b:
foreign key (y) references a (x) on delete set null) type=innodb:
You have defined a SET NULL condition though some of the
columns are defined as NOT NULL.
[.... snip snip snip ...]