Bogus foreign key constraint fail - mysql

I get this error message:
ERROR 1217 (23000) at line 40: Cannot
delete or update a parent row: a
foreign key constraint fails
... when I try to drop a table:
DROP TABLE IF EXISTS `area`;
... defined like this:
CREATE TABLE `area` (
`area_id` char(3) COLLATE utf8_spanish_ci NOT NULL,
`nombre_area` varchar(30) COLLATE utf8_spanish_ci NOT NULL,
`descripcion_area` varchar(100) COLLATE utf8_spanish_ci NOT NULL,
PRIMARY KEY (`area_id`),
UNIQUE KEY `nombre_area_UNIQUE` (`nombre_area`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
The funny thing is that I already dropped all other tables in the schema that have foreign keys against area. Actually, the database is empty except for the area table.
How can it possibly have child rows if there isn't any other object in the database? As far as I know, InnoDB doesn't allow foreign keys on other schemas, does it?
(I can even run a RENAME TABLE area TO something_else command :-?)

On demand, now as an answer...
When using MySQL Query Browser or phpMyAdmin, it appears that a new connection is opened for each query (bugs.mysql.com/bug.php?id=8280), making it neccessary to write all the drop statements in one query, eg.
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE my_first_table_to_drop;
DROP TABLE my_second_table_to_drop;
SET FOREIGN_KEY_CHECKS=1;
Where the SET FOREIGN_KEY_CHECKS=1 serves as an extra security measure...

Two possibilities:
There is a table within another schema ("database" in mysql terminology) which has a FK reference
The innodb internal data dictionary is out of sync with the mysql one.
You can see which table it was (one of them, anyway) by doing a "SHOW ENGINE INNODB STATUS" after the drop fails.
If it turns out to be the latter case, I'd dump and restore the whole server if you can.
MySQL 5.1 and above will give you the name of the table with the FK in the error message.

Disable foreign key checking
SET FOREIGN_KEY_CHECKS=0

from this blog:
You can temporarily disable foreign key checks:
SET FOREIGN_KEY_CHECKS=0;
Just be sure to restore them once you’re done messing around:
SET FOREIGN_KEY_CHECKS=1;

hopefully its work
SET foreign_key_checks = 0;
DROP TABLE table name;
SET foreign_key_checks = 1;

On Rails, one can do the following using the rails console:
connection = ActiveRecord::Base.connection
connection.execute("SET FOREIGN_KEY_CHECKS=0;")

Maybe you received an error when working with this table before. You can rename the table and try to remove it again.
ALTER TABLE `area` RENAME TO `area2`;
DROP TABLE IF EXISTS `area2`;

i found an easy solution, export the database, edit it what you want to edit in a text editor, then import it. Done

Cannot delete or update a parent row: a foreign key constraint fails (table1.user_role, CONSTRAINT FK143BF46A8dsfsfds##5A6BD60 FOREIGN KEY (user_id) REFERENCES user (id))
What i did in two simple steps . first i delete the child row in child table like
mysql> delete from table2 where role_id = 2 && user_id =20;
Query OK, 1 row affected (0.10 sec)
and second step as deleting the parent
delete from table1 where id = 20;
Query OK, 1 row affected (0.12 sec)
By this i solve the Problem which means Delete Child then Delete parent
i Hope You got it. :)

Related

How to drop auto_increment from a mysql table

this should be a very easy issue but I couldn't find a solution that works.
I migrate the date from Oracle to MYSQL and during the process, all primary keys were set to auto_increment.
However, there are a lot of identified relationships (parent PK is the same of children).
So the correct way to do the transaction is to insert into the parent tables, get result.insertId from this interaction and then insert the same value in the child table. I know that I could simply ignore the auto_increment sending the id in the insert command but I didn't like to just let this go.
As the solutions I read about say that I need to change the column to the exactly the same specification but auto_increment, I run the following SQL:
alter table added_object modify column id_interaction_object int(11) not null;
.. And I get the following message:
ERROR 1833 (HY000): Cannot change column 'id_interaction_object': used
in a foreign key constraint 'FK__METRIC__ADDED_OBJECT' of table
'metric'
Any tips?
Thanks
You need to disable foreign key checks:
SET FOREIGN_KEY_CHECKS=0;
alter table added_object modify column id_interaction_object int(11) not null;
SET FOREIGN_KEY_CHECKS=1;

MySQL configuration, allow truncate to execute when reference table is empty

I have the exact same code running on two different servers:
Truncate table2;
Truncate table1;
Both table structures are exactly the same in both servers, table2 has a foreign key referencing table1.
Since table2 was truncated before table1, it is empty and there are no keys pointing to table1, so truncating table2 shouldn't be a problem. But!!!:
In one server it works perfectly well and on the other I get a foreign key constraint error:
Cannot truncate a table referenced in a foreign key constraint (user`.`table2`,
CONSTRAINT `table2_ibfk_1` FOREIGN KEY (`ID`) REFERENCES `user`.`table1` (`ID`))
I can understand from this that there must be a setting that can be changed in order to always allow to truncate empty tables. If not server one should give me the same error.
I know I can use delete instead but it is a longer process and auto_increment needs to be reset in that case.
I just want to understand why server 1 has no error and server 2 does.
Any ideas?
Thanks.
SET FOREIGN_KEY_CHECKS=0; TRUNCATE table1; SET FOREIGN_KEY_CHECKS=1;

InnoDB mySQL unable to set "ON DELETE SET DEFAULT'. How to set?

I am trying to create a table named EMPLOYEE. When I use the following statements without "ON DELETE SET DEFAULT" it is working.
Here is the Error I get with "ON DELETE SET DEFAULT":
ERROR 1005 (HY000): Can't create table 'COMPANY.EMPLOYEE' (errno: 150)
Here is the DDL
CREATE TABLE EMPLOYEE (
Fname VARCHAR(15) NOT NULL,
Minit CHAR, Lname VARCHAR(15) NOT NULL,
Ssn CHAR(9) NOT NULL DEFAULT '123456789',
Bdate DATE, ADDRESS VARCHAR(30),
Sex CHAR, Salary DECIMAL(10,2),
Super_Ssn CHAR(9) NOT NULL DEFAULT '123456789',
Dno INT NOT NULL DEFAULT -99,
PRIMARY KEY (Ssn),
FOREIGN KEY (Super_Ssn) REFERENCES COMPANY.EMPLOYEE(Ssn)
ON DELETE SET DEFAULT
ON UPDATE CASCADE )ENGINE=InnoDB;
Please help me!!! and Thanks in advance :)
You can't use ON DELETE SET DEFAULT or ON UPDATE SET DEFAULT with InnoDB
InnoDB and FOREIGN KEY Constraints
While SET DEFAULT is allowed by the MySQL Server, it is rejected as
invalid by InnoDB. CREATE TABLE and ALTER TABLE statements using this
clause are not allowed for InnoDB tables.
You may try ON DELETE SET NULL if it fits your needs
If ON UPDATE CASCADE or ON UPDATE SET NULL recurses to update the same
table it has previously updated during the cascade, it acts like
RESTRICT. This means that you cannot use self-referential ON UPDATE
CASCADE or ON UPDATE SET NULL operations. This is to prevent infinite
loops resulting from cascaded updates. A self-referential ON DELETE
SET NULL, on the other hand, is possible, as is a self-referential ON
DELETE CASCADE. Cascading operations may not be nested more than 15
levels deep
Here is SQLFiddle demo
just use SET NULL rule and define trigger which will try to set to default value with exception handler if your default value has been deleted from master table
You delete your parent table, which triggers the set default in the
child. The DB tries to set the child records to their default 0. But
there's no 0 record in the parent table, triggering the foreign key
violation.
Check out the MySQL manual about foreign key constrains:
If you re-create a table that was dropped, it must have a definition
that conforms to the foreign key constraints referencing it. It must
have the right column names and types, and it must have indexes on the
referenced keys, as stated earlier. If these are not satisfied, MySQL
returns error number 1005 and refers to error 150 in the error
message.
A few ideas:
Better drop the tables and create it new with a well formed syntax.
Make sure to add ENGINE=InnoDB; to your CREATE TABLE - command.
Make sure InnoDB is enabled on your MySQL server. To verify this, try this command: SHOW VARIABLES LIKE 'have_innodb'; - if it returns a YES, then InnoDB is enabled.
Check your command for upper- and lowercases in table- and fieldnames.
Check this not only one the table you want to create, but also on the tables the foreign keys are referring to.
Make sure your referred tables are properly indexed.
"When creating a foreign key constraint, MySQL requires a usable index on both the referencing table and also on the referenced table. The index on the referencing table is created automatically if one doesn't exist, but the one on the referenced table needs to be created manually (Source). Yours appears to be missing."
See MySQL Foreign Key Error 1005 errno 150

Failing to drop or truncate a table

I tried every thing to truncate a table, but I always have the same message :
Cannot delete or update a parent row: a foreign key constraint fails (`mybdd`.`c_member`, CONSTRAINT `fk_cm_c_id` FOREIGN KEY (`c_id`) REFERENCES `comment` (`c_id`))
Looking some posts on this site I tried this :
ALTER TABLE comment
ADD CONSTRAINT c_member FOREIGN KEY (c_id)
REFERENCES comment (c_id);
But it doens't work :
Can't create table 'mybdd.#sql-2ee0_3769864' (errno: 150){"success":false,"error":"
1005 - Can't create table 'sameditrbdd.#sql-2ee0_3769864' (errno: 150)</div>"}
How can I do that ?
You need to delete all references to the table, including all foreign key constraints and indexes, before you can drop a table.
Foreign key constraints can also prevent you from deleting specific rows.
Alternatively, you can turn off foreign key checks, but then setting them back on again will likely result in errors or unpredictable behavior (because your constraints are violated by the data in the data base).
You can use:
SET foreign_key_checks = 0;
DROP <your_table>
SET foreign_key_checks = 1;
Very likely some people or their process holding your table hostage!!!
You should try to kill them addressing them by their spid #!
To see who is holding your table hostage, you open up your query analyser to run
execute sp_who2 'active' -- under the database of interest
Then, make your own judgment whether it is OK to kill them or not, or call those who logged in.
To kill, just do
kill 999 -- your spid # found in that table returned by above command
After that, try to truncate or drop again!
Best luck!!!

Can't drop table: A foreign key constraint fails

In MySQL I want to drop a table.
I tried a lot things but I keep getting the error that the table named bericht can't be dropped. This is the error I'm getting:
#1217 - Cannot delete or update a parent row: a foreign key constraint fails
How do I drop this table?
This should do the trick:
SET FOREIGN_KEY_CHECKS=0; DROP TABLE bericht; SET FOREIGN_KEY_CHECKS=1;
As others point out, this is almost never what you want, even though it's whats asked in the question. A more safe solution is to delete the tables depending on bericht before deleting bericht. See CloudyMarble answer on how to do that. I use bash and the method in my post to drop all tables in a database when I don't want to or can't delete and recreate the database itself.
The #1217 error happens when other tables has foreign key constraints to the table you are trying to delete and you are using the InnoDB database engine. This solution temporarily disables checking the restraints and then re-enables them. Read the documentation for more. Be sure to delete foreign key restraints and fields in tables depending on bericht, otherwise you might leave your database in a broken state.
Try this:
SELECT *
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME = 'YourTable';
This should deliver you which Tables have references to the table you want to drop, once you drop these references, or the datasets which reference datasets in this table you will be able to drop the table
But fortunately, with the MySQL FOREIGN_KEY_CHECKS variable, you don't have to worry about the order of your DROP TABLE statements at all, and you can write them in any order you like -- even the exact opposite -- like this:
SET FOREIGN_KEY_CHECKS = 0;
drop table if exists customers;
drop table if exists orders;
drop table if exists order_details;
SET FOREIGN_KEY_CHECKS = 1;
For more clarification, check out the link below:
http://alvinalexander.com/blog/post/mysql/drop-mysql-tables-in-any-order-foreign-keys/
Use show create table tbl_name to view the foreign keys
You can use this syntax to drop a foreign key:
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol
There's also more information here (see Frank Vanderhallen post):
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
This probably has the same table to other schema the reason why you're getting that error.
You need to drop first the child row then the parent row.
I realize this is stale for a while and an answer had been selected, but how about the alternative to allow the foreign key to be NULL and then choose ON DELETE SET NULL.
Basically, your table should be changed like so:
ALTER TABLE 'bericht'
DROP FOREIGN KEY 'your_foreign_key';
ALTER TABLE 'bericht'
ADD CONSTRAINT 'your_foreign_key' FOREIGN KEY ('column_foreign_key') REFERENCES 'other_table' ('column_parent_key') ON UPDATE CASCADE ON DELETE SET NULL;
Personally I would recommend using both "ON UPDATE CASCADE" as well as "ON DELETE SET NULL" to avoid unnecessary complications, however your set up may dictate a different approach.
Hope this helps.