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>)
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
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!
I have a table which is using to map two primary keys of other two tables. i make these two fields as foreign keys. The mapping table has no primary key When i am trying to insert 2 value which already in that two tables, i am getting Cannot add or update a child row: a foreign key constraint fails error.
How can i solve this issue ?
My Table is like this :
CREATE TABLE IF NOT EXISTS fuse_package_component_members
( component_id int(11) NOT NULL,
member_type int(11) NOT NULL,
member_id int(11) NOT NULL,
active_date date NOT NULL,
inactive_date date NOT NULL,
KEY component_id (component_id),
KEY member_id (member_id) )
ENGINE=InnoDB DEFAULT CHARSET=latin1
ALTER TABLE fuse_package_component_members
ADD CONSTRAINT comp_id_fk
FOREIGN KEY (component_id) REFERENCES fuse_component_definition (component_id) ON UPDATE NO ACTION,
ADD CONSTRAINT ele_id_fk
FOREIGN KEY (member_id) REFERENCES fuse_product_element (element_id)
ON DELETE NO ACTION ON UPDATE NO ACTION;
SET foreign_key_checks = 0;
UPDATE ...
SET foreign_key_checks = 1;
https://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html
Remove the foreign key constraint from the table, insert the data and re-enforce the constraint..
ALTER TABLE table_name
DROP FOREIGN KEY constraint_name
if you want to check the constraint name, just run the query
show create table table_name
It will show you the whole schema along with all the imposed constraints...
Add the constraints again
A good link to follow -> http://www.w3schools.com/sql/sql_foreignkey.asp
Trying to explain the REFERENCES CONSTRAINT to someone else with a MySQL example, and I can't make the pesky example work! It seems to work if I define it as a FOREIGN KEY, but I've textbooks that say I don't have to do that (making it a column-level referential constraint rather than a table-level one).
The question is, after the UPDATE to dname in the dept table, why doesn't the dname in the emp table change?
-- SQL CODE BEGINS
DROP TABLE IF EXISTS dept;
DROP TABLE IF EXISTS emp;
CREATE TABLE dept (
dname CHAR(10),
dnum numeric(3,0)
) ENGINE=InnoDB;
CREATE TABLE emp (
dname CHAR(10) REFERENCES dept(dname) ON UPDATE CASCADE,
ename CHAR(10)
) ENGINE=InnoDB;
INSERT INTO dept VALUES ("AAA", 111);
INSERT INTO dept VALUES ("BBB", 222);
INSERT INTO emp VALUES ("CCC", "Carol");
INSERT INTO emp VALUES ("AAA", "Alice");
SELECT * from dept;
SELECT * from emp;
UPDATE dept SET dname="XYZ" WHERE dnum=111;
SELECT * from dept;
SELECT * from emp;
-- SQL CODE ENDS
ARGH!
DECLARE dept.dname AS PRIMARY KEY
create a FOREIGN KEY constraint on emp.dname
FULL DDL:
CREATE TABLE dept
(
dname CHAR(10) PRIMARY KEY,
dnum numeric(3,0)
) ENGINE=InnoDB;
CREATE TABLE emp
(
dname CHAR(10) ,
ename CHAR(10),
CONSTRAINT em_FR FOREIGN KEY (dname)
REFERENCES dept(dname) ON UPDATE CASCADE
) ENGINE=InnoDB;
SQLFiddle Demo
excerpted from MySQL 5.5 Reference Manual
<snip>
InnoDB does not recognize or support “inline REFERENCES specifications” (as defined in the SQL standard) where the references are defined as part of the column specification. InnoDB accepts REFERENCES clauses only when specified as part of a separate FOREIGN KEY specification. For other storage engines, MySQL Server parses and ignores foreign key specifications.
</snip>
http://dev.mysql.com/doc/refman/5.5/en/create-table.html
I think the authors of your two textbooks should have noted that their recommended approach, adding "REFERENCES" clause on the column definition, does NOT create or enforce foreign key constraints.
In order to create a foreign key constraint, you need a unique index on the target column(s). In your case, you nee an index on dept(dname).
ALTER TABLE dept ADD CONSTRAINT dept_UX
UNIQUE KEY (dname) ;
With that in place, you can then create a foreign key constraint:
ALTER TABLE emp ADD CONSTRAINT FK_emp_dept
FOREIGN KEY (dname) REFERENCES dept(dname) ON UPDATE CASCADE ;
(Normally, a foreign key references the PRIMARY KEY of a table. But a UNIQUE KEY is sufficient. Actually, with InnoDB, all that is required is an index, it doesn't have to be unique, but we don't want to go there.)
To declare dname to be the PRIMARY KEY rather than a UNIQUE KEY:
ALTER TABLE dept ADD PRIMARY KEY (dname) ;
When the REFERENCES clause is added to the column definition, I believe that gets ignored by MySQL. (The syntax is accepted, but it doesn't get recorded in the data dictionary. If you're working with MyISAM it doesn't matter, since MyISAM doesn't enforce foreign key constraints.)
To create foreign key constraints as part of the table definition, I put that on a separate line:
CREATE TABLE emp (
dname CHAR(10),
ename CHAR(10),
CONSTRAINT FK_emp_dept FOREIGN KEY (dname) REFERENCES dept(dname)
) ENGINE=InnoDB ;
Suppose this is the SQL code of the table:
CREATE TABLE `user_is_in` (
`id_user` INT NULL ,
`id_city` INT NULL ,
`when` DATETIME NULL ,
INDEX `fk_user` (`id_user` ASC) ,
INDEX `fk_city` (`id_city` ASC) ,
CONSTRAINT `fk_user`
FOREIGN KEY (`id_user` )
REFERENCES `user` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_city`
FOREIGN KEY (`id_city` )
REFERENCES `city` (`id` )
ON DELETE SET NULL
ON UPDATE CASCADE)
ENGINE = InnoDB;
The use of the table is to store kind of Foursquare checkins (A user was registered on one place at one time).
Now I have 2 options:
Create an unique index with the 3 fields and no primary key:
UNIQUE INDEX id_user_is_in_UNIQUE (id_user ASC, id_city ASC, when ASC)
Create an additional classic id autoincrement field
I don't like the 2nd option because I want to create queries over users and cities (i.e.: search all users who made a checkin in a city on one date)
Thanks in advance.
You should do both. Add an auto-incrementing primary key and add a uniqueness constraint against all three columns. With a separate system assigned keys you make it easier to define foreign keys to this new table, if and when eventually required. And having the uniqueness constraint against all three columns will ensure that duplicate data is not created.
Some quick side notes:
Since this is an association table, your columns really should be
NOT NULL.
You probably want to CASCADE delete's of a city down to the
association table.