mysql cannot create foreign key - mysql

here are my two tables
CREATE TABLE IF NOT EXISTS `carslibrary` (
`CarID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`CarName` varchar(255) NOT NULL,
`colorslibrary_ID` int(11) unsigned NOT NULL,
PRIMARY KEY (`CarID`),
KEY `colorslibrary_ID` (`colorslibrary_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
CREATE TABLE IF NOT EXISTS `colorslibrary` (
`ColorID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ColorName` varchar(255) NOT NULL,
PRIMARY KEY (`ColorID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
I get an error on the following query:
ALTER TABLE `carslibrary` ADD FOREIGN KEY ( `colorslibrary_ID` )
REFERENCES `cars2`.`colorslibrary` (`ColorID` );
MySQL says:
#1452 - Cannot add or update a child row: a foreign key constraint
fails (`cars2`.<result 2 when explaining filename
'#sql-cf8_41a'>, CONSTRAINT `#sql-cf8_41a_ibfk_1` FOREIGN KEY
(`colorslibrary_ID`) REFERENCES `colorslibrary` (`ColorID`))

Your tables aren't empty, therefore a constraint fails (reference not found) when you create it.
Use SET FOREIGN_KEY_CHECKS = 0; and re-run your alter table.

I would firstly identify orphaned rows in the carslibrary table:
select * from carslibrary where colorslibrary_ID not in (select ColorID from cars2.colorslibrary);
Then decide what you want to do with these orphaned rows. Want to DELETE them from the carslibrary table? UPDATE them to an existing parent ColorID in the colorslibrary? INSERT a new ColorID in the colorslibrary table to cater for the orphaned rows?
Once you've tidied up your data you should be able to run the ALTER TABLE with no errors.

Related

foreign key shall automatically create a new entry

I have 2 tables users and iom.
Primary key of users is iomid and of course in iom the foreign key is iomid that references users.iomid.
If i create a new user in users, I want it automatically inserted into iom aswell without making a second statement.
How can I do it?
iom:
CREATE TABLE IF NOT EXISTS `iom` (
`id` int(11) NOT NULL,
`iomid` varchar(50) NOT NULL,
`subscribed` int(11) DEFAULT NULL,
`workoutcounter` int(11) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
ALTER TABLE `iom`
ADD UNIQUE KEY `id` (`id`), ADD KEY `iom_ibfk_1` (`iomid`);
ALTER TABLE `iom`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `iom`
ADD CONSTRAINT `iom_ibfk_1` FOREIGN KEY (`iomid`) REFERENCES `users` (`iomid`) ON DELETE CASCADE ON UPDATE CASCADE;
user:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL,
`iomid` varchar(50) NOT NULL,
`name` varchar(50) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
ALTER TABLE `users`
ADD PRIMARY KEY (`iomid`), ADD UNIQUE KEY `id` (`id`);
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
Thanks and greetings!
Now that I look at your question again, the issues with your foreign key conventions are fairly irrelevant. Even with more typical relations, foreign key constraints cannot create rows; at most, they can "cascade" updates and deletes of referenced values to referencing tables.
What you need is an "AFTER INSERT ON users" trigger. (Documentation here.)

MySQL Error Number: 1452 (unusual case)

I tried adding a Foreign Key using this query:
ALTER TABLE `StripeBilling`
ADD CONSTRAINT `StripeBillingPatientRef`
FOREIGN KEY (PatientRef)
REFERENCES `Patient`(`PatientId`)
ON DELETE SET NULL;
My tables mysql_dump is:
CREATE TABLE IF NOT EXISTS `StripeBilling` (
...
`PatientRef` int(10) unsigned DEFAULT NULL,
...
) ENGINE=InnoDB AUTO_INCREMENT=10000000 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `StripeBilling`
ADD PRIMARY KEY (`StripeBillingId`), ADD KEY `StripeBillingAgentRef` (`AgentRef`), ADD KEY `PatientRef` (`PatientRef`);
ALTER TABLE `StripeBilling`
MODIFY `StripeBillingId` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=10000000;
ALTER TABLE `StripeBilling`
ADD CONSTRAINT `StripeBillingAgentRef` FOREIGN KEY (`AgentRef`) REFERENCES `Agent` (`AgentId`) ON DELETE SET NULL;
And patient's table is:
CREATE TABLE IF NOT EXISTS `Patient` (
`PatientId` int(10) unsigned NOT NULL,
...
) ENGINE=InnoDB AUTO_INCREMENT=10000000 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `Patient`
ADD PRIMARY KEY (`PatientId`), ADD UNIQUE KEY `PatientSerial` (`PatientSerial`);
ALTER TABLE `Patient`
MODIFY `PatientId` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=10000000;
But MySQL returns an error:
Cannot add or update a child row: a foreign key constraint fails
(newportal_enc.#sql-3863_9f, CONSTRAINT StripeBillingPatientRef
FOREIGN KEY (PatientRef) REFERENCES Patient (PatientId) ON
DELETE SET NULL)
I'm confused because table newportal_enc.#sql-3863_9f does not exist in my database.
This is not due to the presence of the PatientRef index, becouse after removing of this index my issue still exists.
Why am I getting this error and how can I solve it?

Cannot delete or update a parent row

When I try and delete a movie from my database I get a the above error. I believe I have some how made the rated table have precedence over the films table.
How do I make the film table have precedence of the rated table
DELETE FROM `film`.`films` WHERE `films`.`movie_id` =16
--
-- Table structure for table `films`
--
CREATE TABLE IF NOT EXISTS `films` (
`movie_id` int(4) NOT NULL AUTO_INCREMENT,
`movie_title` varchar(100) NOT NULL,
`actor` varchar(100) NOT NULL,
PRIMARY KEY (`movie_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;
CREATE TABLE IF NOT EXISTS `rated` (
`rated_id` int(4) NOT NULL AUTO_INCREMENT,
`rated_name` varchar(40) NOT NULL,
`movie_id` int(4) DEFAULT NULL,
PRIMARY KEY (`rated_id`),
KEY `movie_id` (`movie_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
ALTER TABLE `rated`
ADD CONSTRAINT `rated_ibfk_1` FOREIGN KEY (`movie_id`) REFERENCES `films` (`movie_id`);
The foreign key you have defined on movie_id by default restricts the deletion: with the current schema you cannot delete a film as long as it has ratings.
You can automatically delete the ratings when you delete the film using cascading delete. Whether this is the best option for your application is for you to decide...
ALTER TABLE `rated` ADD FOREIGN KEY (`movie_id`)
REFERENCES `films` (`movie_id`) ON DELETE CASCADE;
Since there is a foreign key constraint you have to first delete any child records before you can delete the parent.
Try deleting everything from Rated table first, then deleting from films table.
DELETE FROM Rated
WHERE Movie_ID = 16
DELETE FROM Films
WHERE Movie_ID = 16

MySQL foreign key ON DELETE SET NULL check data types error

I'm working on a normalised database, to be secure I wanted to use foreign keys.
My database:
CREATE TABLE `names` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
KEY `name_2` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name_id` (`name_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
The command:
ALTER TABLE `names` ADD FOREIGN KEY ( `name` ) REFERENCES `temp`.`users` (
`name_id`
) ON DELETE SET NULL ON UPDATE CASCADE ;
The response (error):
Error creating foreign key on name (check data types)
So, how to fix this?
The error is self explanatory. Name in names table is of type varchar(250) whereas name_id in users table is of type int(11).
But I believe you meant to have an FK all the way around in users table referencing names table.
ALTER TABLE users
ADD FOREIGN KEY (name_id) REFERENCES names (id)
ON DELETE SET NULL ON UPDATE CASCADE;
Here is SQLFiddle demo
Both keys have to be the same type and length,you have varchar and int.
Here is what you want:
ALTER TABLE `names` ADD FOREIGN KEY ( `id` ) REFERENCES `users` (
`name_id`)

MySQL foreign keys with non-identifying relationships

All I need is to create 2 tabeles with next structure:
The SQL:
CREATE TABLE IF NOT EXISTS `ds_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `module_news_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) NOT NULL,
`cat_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_module_news_cats_module_news_cats` (`parent`),
KEY `fk_module_news_cats_ds_cats1` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
ALTER TABLE `module_news_cats`
ADD CONSTRAINT `fk_module_news_cats_ds_cats1` FOREIGN KEY (`cat_id`) REFERENCES `ds_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_module_news_cats_module_news_cats` FOREIGN KEY (`parent`) REFERENCES `module_news_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
But when I try to insert first row to my table "module_news_cats", I recive next error:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`empty`.`module_news_cats`, CONSTRAINT `fk_module_news_cats_module_news_cats` FOREIGN KEY (`parent`) REFERENCES `module_news_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Question:
How I can create table which will have an index with non-identifying relationship to the anther index in the same table? Some rows will have parents, and some not.
I think you just need to allow NULLs in module_news_cats.parent:
CREATE TABLE IF NOT EXISTS `module_news_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) NULL, -- Change this
`cat_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_module_news_cats_module_news_cats` (`parent`),
KEY `fk_module_news_cats_ds_cats1` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
and then if there isn't a parent, create the row with a NULL in parent.
Your 'parent' field cannot be empty (NULL) if you insert a record, which means that every record you insert should refer to a parent ID (which is impossible if there are no entries in your table yet).
If you make the 'parent' field in the module_news_cats table nullable:
ALTER TABLE `module_news_cats` CHANGE `parent` `parent` INT( 11 ) NULL DEFAULT NULL
you should be able to insert records that have no parent ID associated (just supply NULL instead of a value).
You could make the parent column in the module_news_cats table nullable.
Then for rows that have no parents populate the parent column with null.