I am very new to SQL and MySQL. I am trying to modify a primary key column in a table so that it auto-increments. This primary key is also a foreign key in another table. I am not able to modify this column due to an error related to the foreign key in the other table. Here is the error:
mysql> desc favourite_food;
+-----------+----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------------------+------+-----+---------+-------+
| person_id | smallint(5) unsigned | NO | PRI | 0 | |
| food | varchar(20) | NO | PRI | | |
+-----------+----------------------+------+-----+---------+-------+
2 rows in set (0.09 sec)
mysql> alter table person modify person_id smallint unsigned auto_increment;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 22
Current database: bank
ERROR 1833 (HY000): Cannot change column 'person_id': used in a foreign key cons
traint 'fk_fav_food_person_id' of table 'bank.favourite_food'
mysql>
I'm sure it is something simple, but I can't figure out why and teh book I am following does not indicate why. Thanks.
Do it something like this
--Drop fk
ALTER TABLE favourite_food DROP FOREIGN KEY fk_fav_food_person_id;
--Alter your pk
ALTER TABLE person modify person_id smallint unsigned auto_increment;
--Recreate fk
ALTER TABLE favourite_food ADD CONSTRAINT fk_fav_food_person_id FOREIGN KEY (person_id) REFERENCES person (person_id) ON DELETE CASCADE;
Haven't checked syntax exactly, but should be close
Execute your SQL again and then run
show engine innodb status
Type the above command onto your MySQL command prompt. It should help you with more info on why the SQL failed to execute.
Try this otherwise:
show innodb status
Take a look here:
Error code 1005, SQL state HY000: Can't create table errno: 150
You cannot alter a primary key as it is referenced as a foreign key in other table. This is because of the referential integrity constraint.
Referential Integrity Although the main purpose of a foreign key constraint is to control the data that can be stored in the foreign
key table, it also controls changes to data in the primary key table.The constraint enforces referential integrity by guaranteeing that changes cannot be made to data in the primary key table if those changes invalidate the link to data in the foreign key table. If an attempt is made to delete the row in a primary key table or to change a primary key value, the action will fail when the deleted or changed primary key value corresponds to a value in the foreign key constraint of another table. To successfully change or delete a row in a foreign key constraint, you must first either delete the foreign key data in the foreign key table or change the foreign key data in the foreign key table, which links the foreign key to different primary key data.
Cascading Referential Integrity
By using cascading referential integrity constraints, you can define
the actions that the Database Engine takes when a user tries to delete
or update a key to which existing foreign keys point. The following
cascading actions can be defined.
NO ACTION
The Database Engine raises an error and the delete or update action on
the row in the parent table is rolled back.
CASCADE
Corresponding rows are updated or deleted in the referencing table
when that row is updated or deleted in the parent table. CASCADE
cannot be specified if a timestamp column is part of either the
foreign key or the referenced key. ON DELETE CASCADE cannot be
specified for a table that has an INSTEAD OF DELETE trigger. ON UPDATE
CASCADE cannot be specified for tables that have INSTEAD OF UPDATE
triggers.
SET NULL
All the values that make up the foreign key are set to NULL when the
corresponding row in the parent table is updated or deleted. For this
constraint to execute, the foreign key columns must be nullable.
Cannot be specified for tables that have INSTEAD OF UPDATE triggers.
SET DEFAULT
All the values that make up the foreign key are set to their default
values if the corresponding row in the parent table is updated or
deleted. For this constraint to execute, all foreign key columns must
have default definitions. If a column is nullable, and there is no
explicit default value set, NULL becomes the implicit default value of
the column. Cannot be specified for tables that have INSTEAD OF UPDATE
triggers.
CASCADE, SET NULL, SET DEFAULT and NO ACTION can be combined on tables
that have referential relationships with each other. If the Database
Engine encounters NO ACTION, it stops and rolls back related CASCADE,
SET NULL and SET DEFAULT actions. When a DELETE statement causes a
combination of CASCADE, SET NULL, SET DEFAULT and NO ACTION actions,
all the CASCADE, SET NULL and SET DEFAULT actions are applied before
the Database Engine checks for any NO ACTION.
Related
I have following problem:
This is my code in MySQL:
create table fremd(
id int primary key,
name varchar(20),
foreign key(id) references mensch(id) on delete set null
);
id is the primary key of this table but also a foreign key which is referencing to the primary key of table mensch. The problem is the on delete set null statement. When I use cascade instead of set null it works. But with set null it doesnt work. What can i do?
This is the error message:
08:39:00 Error Code: 1215. Cannot add foreign key constraint 2.609 sec
You have two conflicting declarations in your CREATE TABLE:
id int primary key
This basically means that id is Primary Key. Now, a Primary key basically fulfills following two constraints:
It will be Unique. So, no two rows cannot have same value for id.
It will be NOT NULL. So, it can never be set as NULL.
On the other hand, your Foreign key definition states:
foreign key(id) references mensch(id) on delete set null
ON DELETE SET NULL basically means that when the parent table id value is deleted, the child table (this table's) id value is set to NULL. This directly conflicts with the Primary Key declaration, which stops it from becoming NULL.
That is why your foreign key cannot be defined. You can now use any of the following options to resolve this. But these options will have to be carefully determined based on your business logic:
Make id UNIQUE key instead of Primary Key. This will ensure that it remains a Unique value, as well as NULL can be used in it.
Change Foreign Key's ON DELETE behvaiour to something else, like, CASCADE (this will delete the child table row, when parent table row is deleted), or, RESTRICT (this will block the deletion from parent table).
I'm having a problem regarding SQLyog Foreign Key relationship creation when I execute this query:
Error:
Cannot add or update a child row: a foreign key constraint fails
(zestagio.#sql-6dc_4b6151, CONSTRAINT FK_CARRO FOREIGN KEY
(CARRO) REFERENCES km_carro (IDCARRO))
MySQL Query:
ALTER TABLE `zestagio`.`km_colaboradores`
ADD COLUMN `CARRO` int(11) NOT NULL after `TIPO`,
ADD CONSTRAINT `FK_CARRO` FOREIGN KEY (`CARRO`) REFERENCES `zestagio`.`km_carro`(`IDCARRO`)
The error message simply means that you have records in km_colaboradores table that do not satisfy the constraint set by FK_CARRO foreign key.
Seeing that the field CARRO is defined as int and not null and there is no default value specified either. The fact that this statement did not raise any error, but the foreign key did, indicates that strict sql mode is not enabled. You probably have data in the table already, so adding the CARRO field this way resulted in it being set 0 for all records. In strict sql mode this would have resulted in an error message already, therefore strict sql mode cannot be enabled.
However, when you tried to add the foreign key, then MySQL did not find any record in km_carro table, where IDCARRO were 0, therefore the existing records break the foreign key constraint.
I suggest to allow CARRO to have null values for the time being, add the foreign key, update CARRO values as required to proper values, only then disallow null values.
The other alternative is to define an explicit default value for CARRO, a value that exists in the IDCARRO field.
CREATE TABLE `profilePic` (
`ClientID` VARCHAR(255) NOT NULL,
PRIMARY KEY (`ClientID`),
CONSTRAINT `FK__user_details` FOREIGN KEY (`ClientID`) REFERENCES `user_details` (`ClientID`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;
I am trying to add table with foreign key and I got this error, why that happend ?
trying doing new table.
i am trying to put same details on user_details->ClientID and profilePic->ClientID
3.i have already one table call`d userdb and in this table i have ClientID and its foreign key and its work.
The below will fail because the collation is different. Why do I show this? Because the OP didn't.
Note I shrunk the size due to error 1071 on sizing for varchar 255 with that collation and then auto chosen charset.
The point being, if collation is different, it won't work.
CREATE TABLE `user_details` (
`ClientID` VARCHAR(100) NOT NULL,
PRIMARY KEY (`ClientID`)
)ENGINE=InnoDB;
CREATE TABLE `profilePic` (
`ClientID` VARCHAR(100) NOT NULL,
PRIMARY KEY (`ClientID`),
CONSTRAINT `FK__user_details` FOREIGN KEY (`ClientID`) REFERENCES `user_details` (`ClientID`) ON UPDATE CASCADE ON DELETE CASCADE
)COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;
The above failure is at the table level. A trickier one causing a 1215 error due to column-level collation mismatches can be seen in This answer.
Pulling the discussion up to more general cases ...
whether you are trying to establish a Foreign Key constraint on table creation or with ALTER TABLE
| ADD [CONSTRAINT [symbol]]
FOREIGN KEY [index_name] (index_col_name,...)
reference_definition
such as
ALTER TABLE `facility` ADD CONSTRAINT `fkZipcode`
FOREIGN KEY (`zipcode`) REFERENCES `allzips`(`zipcode`);
the following will apply.
From the MySQL manual page entitled Using FOREIGN KEY Constraints:
Corresponding columns in the foreign key and the referenced key must
have similar data types. The size and sign of integer types must be
the same. The length of string types need not be the same. For
nonbinary (character) string columns, the character set and collation
must be the same.
In addition, the referenced (parent) table must have a left-most key available for fast lookup (verification). That parent key does not need to be PRIMARY or even UNIQUE. This concept is described in the 2nd chunk below. The first chunk alludes to a Helper index that will be created if necessary in the referencing (child) table if so necessary.
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
InnoDB permits a foreign key to reference any column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
When trying to create a foreign key via HeidiSQL, you get a warning as soon as the selected column data types don't match. I added this warning to HeidiSQL's table designer due to the non-intuitive message from the server ("Cannot add foreign key constraint")
The selected foreign column do not match the source columns data type and unsigned flag. This will give you an error message when trying to save this change. Please compare yourself:
I have a MySQL table whose definition is as follows:
CREATE TABLE `guestbook` (
`Id` int(10) unsigned NOT NULL,
`ThreadId` int(10) unsigned NOT NULL,
PRIMARY KEY (`Id`),
KEY `ThreadId` (`ThreadId`),
CONSTRAINT `guestbook_ibfk_1` FOREIGN KEY (`ThreadId`) REFERENCES `guestbook` (`Id`)
) ENGINE=InnoDB;
and currently there's only 1 row in the table:
mysql> select * from guestbook;
+-----+----------+
| Id | ThreadId |
+-----+----------+
| 211 | 211 |
+-----+----------+
The problem is that there's no way to delete this row without breaking the constraint.
mysql> delete from guestBook;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`polaris`.`guestbook`, CONSTRAINT `guestbook_ibfk_1` FOREIGN KEY (`ThreadId`) REFERENCES `guestbook` (`Id`))
As the ThreadId column was defined not null, it is also impossible to set the ThreadId to a different value temporarily to delete the row. Is there a way to delete the row without changing the definition of the table or dropping the entire table?
You can temporarily disable foreign key constraints with this query:
SET foreign_key_checks = 0;
If you put an ON DELETE CASCADE action on your foreign key, you should be able to delete rows that are self-referencing.
CONSTRAINT `guestbook_ibfk_1` FOREIGN KEY (`ThreadId`) REFERENCES `guestbook` (`Id`) ON DELETE CASCADE
The benefit this has over using ON DELETE SET NULL is that you don't have to alter your schema to make the "ThreadId" column nullable.
There are several workarounds. The approach suggested by others ...
SET foreign_key_checks = 0;
... will disable the foreign keys of every table. This is not suitable for use in a shared environment.
Another approach is to drop the foreign key using
ALTER TABLE `guestbook`
DROP FOREIGN KEY `guestbook_ibfk_1`
/
We can sort out the data using DML, and then reinstate the foreign key using:
ALTER TABLE `guestbook`
ADD CONSTRAINT `guestbook_ibfk_1` FOREIGN KEY (`ThreadId`)
REFERENCES `guestbook` (`Id`)
/
But is there a way to change the data without executing any DDL? Well, we can insert a new record and change the current record to reference it:
INSERT INTO `guestbook` VALUES (212, 211)
/
UPDATE `guestbook`
SET `ThreadId` = 212
WHERE `Id` = 211
/
Astute observers will have noticed that we have still ended up with a co-dependency, only between records. So we haven't really advanced; we now have two records we cannot delete, instead of one. (Incidentally this applies to whatever DML we might execute while the foreign key is dropped or disabled). So, perhaps we need to reconsider of the data model. Are we modelling a graph with circular dependencies or a hierarchy?
A hierarchical data structure needs at least one root node, a record on which other records can depend but which itself depends on no record. The usual way of implementing this is to make the foreign key column optional. At the toppermost level of the hierarchy the record must have a NULL in that column. Whether there should be only one such root node or whether several would be allowed is a matter for your business rules.
ALTER TABLE `guestbook` MODIFY `ThreadId` int(10) unsigned
/
In modelling terms this is not different from a record which is its own master, but it is a more intuitive solution.
The inability to delete a self-referencing row is a longstanding known bug/outstanding feature request in MySQL.
In many situations where you rub up against this problem you can NULL the foreign key before executing the delete, so your workaround affects only the rows you intend (uses the same WHERE clause).
Ya temporarily disable the foreign key
set foreign_key_checks=0;
If you set an ON DELETE SET NULL on my Foreign Key, it let's me delete a self-referencing. If I don't specify an ON DELETE, MySQL defaults to RESTRICT.
Of course, make sure the column is NULLABLE. You may also try SET DEFAULT depending on what the default is. But remember NO ACTION is just an alias to RESTRICT in MySQL!
Only tested on MySQL 5.6 (which was not released when this question was originally posted).
Well, i have two tables
publica_evento_grupo
Field | Type | Null | Key | Default | Extra
id_evento_grupo int(10) unsigned NO PRI auto_increment
id_evento int(8) unsigned NO MUL
id_grupo int(8) unsigned NO MUL
identificacao varchar(55) NO
publica_identificacao_publicacao
Field | Type | Null | Key | Default | Extra
id_evento int(8) unsigned NO PRI
identificacao varchar(55) NO PRI
publica_evento_grupo.id_evento in is a foreign key to a third table called publica_evento but is also a foreign key together with the column to the table publica_identificacao_publicacao.identificacao. The problem is, I got to create the foreign key that relates publica_evento_grupo to publica_identificacao_publicacao by the key id_evento, but when I try to create the another FK with the column identificacao, it gives the errno below
[Err] 1005 - Can't create table '#sql-1049_1980992' (errno: 150).
As you can see the table publica_identificacao_publicacao has two PK and that iss the reason that it has to be 2 FK to relate them, i didn't create the indexes yet, because as far as i know, i just have to create the indexes after adding the FK contraints, and I was able to create the FK contraint to the column id_evento between evento_grupo and identificacao_publicacao, i don't know why just the column identificacao is giving this error
EDIT 1: #RolandBouman i don't have the permission to use that command SHOW ENGINE INNODB STATUS
EDIT 2: #Geoff_Montee acctually the command you passed worked, to undestand why i use that structure take a look at this question MySQL UNIQUE Constraint multiple columns condition
Without the actuall DDL it's not so easy to say. I recommend doing:
SHOW ENGINE INNODB STATUS;
Immediately after you run into this error. In the output, look for a section that looks like:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
121026 22:40:18 Error in foreign key constraint of table test/#sql-154c_94:
foreign key(rid) references bla(id):
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.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
You'll find detailed info there about what's wrong with your foreign key definition.
That error usually happens because there is a type mismatch between the referring table and the referred table. In this case, the types seem to match.
Have you considered having a constraint for both fields in the primary composite key? You might have to remove the existing foreign key constraint on id_evento first.
ALTER TABLE publica_evento_grupo ADD FOREIGN KEY
(id_evento, identificacao) REFERENCES
publica_identificacao_publicacao (id_evento, identificacao);
It seems as though the error in this case might be because you try to add a foreign key constraint to only part of a composite primary key.
Does identificacao exist in any other tables? Why do you want to add a foreign key constraint to only part of a composite primary key?
Think about it this way...
Let's say you do have a foreign key constraint in the publica_evento_grupo table to the identificacao field by itself. Let's also say in the publica_identificacao_publicacao table you have (1, "some string") and (2, "some string"). So if you delete (2, "some string"), but leave (1, "some string") in its place. The rows that refer to (1, "some string") in the publica_evento_grupo table will complain, even though they shouldn't!
So it sounds to me like you should add a foreign key constraint to all of a primary key or none of it.