error with alter table and foreign key - mysql

I have 2 tables :
Installers (Fields: id,company,country,experience,name)
Contacts (Fields: name,phone,address)
I would like to match both names, thereby I could click in one value of the name of Installers and it could show me the values of Contacts table.
However when I am trying to set up the foreign key (my child table will probably be Installers , as I have more tables like that and Contacts would be the parent.) It states this error:
query SQL:
ALTER TABLE `Installers`
ADD FOREIGN KEY (`name`)
REFERENCES `SOLAR_PV`.`Contacts`(`name`)
ON DELETE CASCADE ON UPDATE CASCADE;
MySQL ha dicho: Documentación
1452 - Cannot add or update a child row: a foreign key constraint
fails (SOLAR_PV.#sql-32a_183, CONSTRAINT #sql-32a_183_ibfk_1
FOREIGN KEY (name) REFERENCES Contacts (name) ON DELETE CASCADE
ON UPDATE CASCADE)
Both tables are InnoDB and Contacts.name is indexed as well as Installers.name
Primary Key of Installers is id and Primary Key of Contacs is name.
Any idea about what would be the problem?

It seems your child table contains few records those don't have in master, you can check it by below query-
SELECT id FROM Installers ins
LEFT JOIN SOLAR_PV.Contacts cnt ON ins.name=cnt.name
WHERE cnt.name IS NULL;
Note: Assuming name is int type for better performance as it is primary key in one table.
If you get few records by above query then you can follow below 2 approach-
Approach1: You can either delete these records in child table or insert in master table also and then you can create relationship by this alter command.
Approach2: If you don't want to change in your tables existing data and still want to execute your alter query then use as per below-
SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE `Installers`
ADD FOREIGN KEY (`name`)
REFERENCES `SOLAR_PV`.`Contacts`(`name`)
ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;

Related

Two columns in same table and same foreign key

I'm developing an application, actually a billing system. Here accountant can add invoice for a client.
I have two tables, users and invoices:
invoices (user_id, created_by)
users (id)
Invoices has two columns, user_id and created_by, I want both to be linked with id of the users table.
Already user_id has been added as foreign key. Now I'm trying to add created_by as foreign key. So issued following command:
ALTER TABLE `invoices`
ADD FOREIGN KEY (`created_by`) REFERENCES `secureap_maind`.`users` (`id`)
ON DELETE RESTRICT ON UPDATE RESTRICT;
And I'm getting an error message.
#1452 - Cannot add or update a child row: a foreign key constraint fails (secureap_maind.#sql-3717_a323d, CONSTRAINT #sql-3717_a323d_ibfk_2 FOREIGN KEY (created_by) REFERENCES users (id))
I'm not sure if I can add two columns as foreign key. IF possible, can you please advice to do that?
Thanks in advance.
This SO post implies that removing your ON DELETE RESTRICT clause from the ALTER TABLE statement might solve your problem. Try running this query instead:
ALTER TABLE `invoices`
ADD FOREIGN KEY (`created_by`) REFERENCES `secureap_maind`.`users`(`id`)
I am assuming that the invoices table was created using InnoDB rather than MyISAM, the latter which does not enforce foreign keys.

Correct way to remove entry from a SQL table along with the relations

If we have TableA and TableB related by TableAB where TableAB has foreign keys for the first two table, then what's the go-to way of deleting an entry from TableA? Up to now if used a property such as IsActive with a bit to describe if the entry is still valid. However, that makes it a little problematic when there are "ghost entries" in the relation tables, such as TableAB.
How should I proceed?
One chaining table in question.
CREATE TABLE EntradaContadorCliente (
ClaveECC int AUTO_INCREMENT not null,
ClaveCliente int not null,
ClaveContador int not null,
ClaveEntrada int not null,
PRIMARY KEY (ClaveECC),
FOREIGN KEY (ClaveCliente) REFERENCES Cliente(ClaveCliente),
FOREIGN KEY (ClaveContador) REFERENCES Contador(ClaveContador),
FOREIGN KEY (ClaveEntrada) REFERENCES EntradaBitacora(ClaveEntrada)
);
Since TableA and TableB related by TableAB; which means TableAB is a chaining table. One way is to use ON DELETE CASCADE for cascading the delete operation on primary table.
Alternative is to, manually delete the entries from your chaining table once the entry has been deleted from primary table.
You can use a ALTER statement to re-create the FK constraint like
ALTER TABLE `TableAB` DROP FOREIGN KEY FK_KEY_Test;
ALTER TABLE `TableAB` ADD CONSTRAINT FK_KEY_Test FOREIGN KEY ('some_column')
REFERENCES `TableA` ('Test_column1') ON UPDATE CASCADE ON DELETE CASCADE;
From MySQL Documentation:
CASCADE: Delete or update the row from the parent table, and
automatically delete or update the matching rows in the child table.
Both ON DELETE CASCADE and ON UPDATE CASCADE are supported.
first you disable all foreign key with:-
alter table table_name
nocheck constraint fk_constraint
then you delete data in parent table.

MySQL: Alter table to set Foreign key

Although there are some similar questions about the subject, I can't find the right answer for my problem. I have 2 tables called customer and car. What I want to do is this: When I delete a customer from database, I want the car that belongs to that customer will be automatically deleted as well. The code that MySQL Workbench generated for me is this:
ALTER TABLE `autocare`.`car`
ADD CONSTRAINT `customerId`
FOREIGN KEY (`CUSTOMER_ID`)
REFERENCES `autocare`.`customer` (`ID`)
ON DELETE CASCADE
ON UPDATE RESTRICT;
And I get this error:
ERROR 1452: Cannot add or update a child row: a foreign key constraint fails
(`autocare`.`#sql-80c_388`, CONSTRAINT `customerId` FOREIGN KEY (`CUSTOMER_ID`)
REFERENCES `customer` (`ID`) ON DELETE CASCADE)
There was no relation between those tables before. Any ideas? Thanks in advance!
Your goal is ultimately to implement a cascading deletion from customer to car. When you attempt to add the constraint with the tables as they are now, it fails because the car table must include rows having a a CUSTOMER_ID value which does not currently exist in the parent customer table.
You should first locate those orphan rows and delete them (since your goal is to delete them anyway). You can find them with a query like:
SELECT *
FROM car
WHERE
CUSTOMER_ID NOT IN (SELECT ID FROM customer)
Once the orphan records are removed, the foreign key constraint can be met by the remaining existing rows and your ALTER TABLE statement will succeed.

Mysql error code 1452 with two tables with different database engines

I have two tables 'mm_ads' and 'mm_users'. 'mm_ads' uses the Myisam database engine, while 'mm_users' uses a InnoDb. From what I read it is impossible to create a foreign key reference in such a situation, becaues the latter engine is transactional and the first one is not. But when I run:
ALTER TABLE mm_ads ADD CONSTRAINT FK_76EC3E1DF132696E3358 FOREIGN KEY (userid) REFERENCES mm_users (id)
No error is shown, it reports the number of effected rows and nothing else. Than I see that the fk is not created just an index on the column in the table. As I studied the problem I found out that the engines of tables are different so I changed the engine of mm_ads to Innodb. But then when I run the command I get this error.
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`admin_pw`.<result 2 when explaining filename '#sql-61b_3019e'>, CONSTRAINT `FK_76EC3E1DF132696E3358` FOREIGN KEY (`userid`) REFERENCES `mm_users` (`id`))
The types of userid and id are the same and I have values in the tables.
I would do the following:
1. Drop The Foreign Key
ALTER TABLE mm_ads DROP FOREIGN KEY `FK_76EC3E1DF132696E3358`;
2. Indentify Orphaned Rows In Child Table
SELECT * FROM mm_ads when userid not in (select id from mm_users);
3. Deal With Orphaned Rows In Child Table
Delete rows from mm_ads? Insert rows into mm_users? Up to you here. Either way you must end up with no orphaned rows in mm_ads based on the mm_ads.userid > mm_users.id relationship.
4. Change Engine
ALTER TABLE mm_ads ENGINE = InnoDB;
5. Restore Foreign Key
ALTER TABLE mm_ads ADD CONSTRAINT FK_76EC3E1DF132696E3358 FOREIGN KEY (userid) REFERENCES mm_users (id);

MySQL: delete a row ignoring foreign key constraint

so I am working on a few tables and there are some data inconsistency between them... One or two tables have a foreign key constraint on a particular table (call it table X), but that table has multiple rows with the foreign key column.
What I want to do is to remove the duplicated rows in table X, but the foreign key constraint is preventing me from doing this. Is there a way to force delete the rows while ignoring the foreign key constraint since I know what I'm doing?
SET foreign_key_checks = 0;
That will prevent MySQL from checking foreign keys. Make sure to set it back to 1 when you are done though.
Also, you could always drop the foreign key and then add it later if you wanted to only affect a singular key
ALTER TABLE tableName DROP FOREIGN KEY fk;
Simply execute as follows:
Disable foreign key check
SET foreign_key_checks = 0;
Delete your records
DELETE FROM table_name WHERE {conditions};
Enable foreign key check
SET foreign_key_checks = 1;
Credit: https://www.knowledgewalls.com/johnpeter/books/mysql/how-to-ignore-constraints-while-insertupdate-or-delete-records-in-mysql
As some people already pointed out, ignoring a restricting foreign key leaves you with database inconsistencies. Preventing DELETEs is something you want in such cases.
You should better delete depending rows prior to the main query:
DELETE FROM cities WHERE country_id=3;
-- Afterwards you delete rows from the parent table without error:
DELETE FROM countries WHERE country_id=3;
Or, even better, change the foreign key once, so it does the deletion automatically (cascading):
ALTER TABLE cities DROP FOREIGN KEY `fk.cities.country_id`;
ALTER TABLE cities ADD CONSTRAINT `fk.cities.country_id` FOREIGN KEY (country_id)
REFERENCES countries (id) ON UPDATE CASCADE ON DELETE CASCADE;
-- From now on, just delete from the parent table:
DELETE FROM countries WHERE country_id=3;
To expand on the accepted answer, you have to specify the constraint name after DROP FOREIGN KEY
You can check the constraint name by issuing SHOW CREATE TABLE.
> SHOW CREATE TABLE tbl_name
Create Table: CREATE TABLE `tbl_name` (
`id` int(11) DEFAULT NULL,
`foo_id` int(11) DEFAULT NULL,
CONSTRAINT `foo_ibfk_1` FOREIGN KEY (`foo_id`)
)
In this case, "foo_ibfk_1" is the constraint name. So you can write:
ALTER TABLE tableName DROP FOREIGN KEY foo_ibfk_1;