MySQL foreign key problem rails - mysql

I'm trying to add foreign keys to my table using the following code:
constraint_name = "fk_#{from_table}_#{to_table}"
execute %{
CREATE TRIGGER #{constraint_name}_insert
BEFORE INSERT ON #{from_table}
FOR EACH ROW BEGIN
SELECT
RAISE(ABORT, "constraint violation: #{constraint_name}")
WHERE
(SELECT id FROM #{to_table} WHERE
id = NEW.#{from_column}) IS NULL
END
}
I'm getting the following error:
Mysql2::Error: Not allowed to return a result set from a trigger:
CREATE TRIGGER fk_brands_products_insert
BEFORE INSERT ON brands
FOR EACH ROW BEGIN
SELECT
RAISE(ABORT, "constraint violation: fk_brands_products")
FROM brands
WHERE
(SELECT id FROM products WHERE id = NEW.brand_id) IS NULL;
END;
What is wrong with my SQL script?

You can add a MySQL Foreign Key constraint like this:
ALTER TABLE #{from_table}
ADD CONSTRAINT #{constraint_name} FOREIGN KEY
(#{from_column}) REFERENCES #{to_table}(id)
This will constrain from_column on from_table to values in id in #{to_table}.
P.S: If you don't want to name the CONSTRAINT you can do this:
ALTER TABLE #{from_table}
ADD FOREIGN KEY
(#{from_column}) REFERENCES #{to_table}(id)

As the error states, a trigger is not allowed to return a result set. Even though you are raising a error, MySql doesn't like the SELECT statement. Try using a IF:
IF EXISTS(SELECT id FROM #{to_table} WHERE
id = NEW.#{from_column}) = 0 THEN
RAISE(ABORT, "constraint violation: #{constraint_name}");
END IF;

Related

How to ignore foreign constraints and add NULL instead

I have two tables which share same primary/foreign key for ID:
Table1: PRIMARY KEY (id));
Table2: FOREIGN KEY (ident) REFERENCES table1(id);
I am trying to create a trigger in order to let me insert new row with non existing primary key and set on that field NULL but i am getting:
Cannot add or update a child row: a foreign key constraint fails error.
How can i solve this issue ?
this is what i tried but so far:
DELIMITER $$
CREATE TRIGGER t1 BEFORE INSERT on table1
FOR EACH ROW
BEGIN
IF NEW.ident!= (
SELECT ident
FROM dimos
WHERE ident NOT IN (
SELECT id
FROM table1
)
)
THEN
SET NEW.ident = 'NULL';
END IF;
END $$
DELIMITER ;
so i expect to get all field in a row expert the foreign key, foreign key must be null!

Error while adding Foreign key

I am using Mysql Workbench. I have already made the table.
Now I want to add foreign key in a table called Personal_Details that key is primary key in Login table.
But when I am trying to do so, it shows me the following error:
ERROR 1005: Can't create table 'shaadiDB.#sql-404_25' (errno: 121)
SQL Statement:
ALTER TABLE `shaadiDB`.`Personal_Details`
ADD CONSTRAINT `Login_Id`
FOREIGN KEY (`Login_Id` )
REFERENCES `shaadiDB`.`Login` (`Login_Id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION
, ADD INDEX `Login_Id` (`Login_Id` ASC)
It seems that the table Personal_Details is having data from which there might be some rows with Login_Id for which entry is not present in table Login.
If this is the case , then solution would be that you need to move the data to another table, then add constraint. After adding the constraint you need to add all rows back to table 1 by 1.
Error 121: This error explicitly is thrown when there is a duplication in key names.
Immediately after running your Alter ... statement, execute the following and observe the results.
SHOW ENGINE InnoDB STATUS;
Description text from the result will tell you on which key name the duplication is found.
Based on that you modify your ALTER ... statement and execute.
Alternatively you can also find if any such duplicate key name is defined by executing:
select constraint_name, constraint_type, table_name
from information_schema.table_constraints
where table_schema = DATABASE() -- and constraint_type = 'foreign key'
Constraint types can be anything like PRIMARY KEY, FOREIGN KEY, etc.
If you see any key names in the result that you are trying to use in your ALTER .. statement, you should modify them and execute.
before adding any constrain to a table that already have some data might cause this problem,try to add constrain with out data

MySQL foreign key constraint error on insert in transaction

I have this error when inserting values into an association table during transaction:
Cannot add or update a child row: a foreign key constraint fails (dev.genre, CONSTRAINT fk_Genre_EntityType1 FOREIGN KEY (idEntityType) REFERENCES entitytype (idEntityType) ON DELETE NO ACTION ON UPDATE NO ACTION)
Here is the part of the schema that describes the tables used:
and here is the create statement of the genre table:
-- -----------------------------------------------------
-- Table `dev`.`Genre`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `dev`.`Genre` (
`idGenre` INT NOT NULL ,
`Name` VARCHAR(45) NULL COMMENT 'musique, spectacle, expo' ,
`idEntityType` INT NOT NULL ,
`idStyle` INT NOT NULL ,
PRIMARY KEY (`idGenre`, `idEntityType`, `idStyle`) ,
INDEX `fk_Genre_EntityType1_idx` (`idEntityType` ASC) ,
INDEX `fk_Genre_Style1_idx` (`idStyle` ASC) ,
CONSTRAINT `fk_Genre_EntityType1`
FOREIGN KEY (`idEntityType` )
REFERENCES `dev`.`EntityType` (`idEntityType` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Genre_Style1`
FOREIGN KEY (`idStyle` )
REFERENCES `dev`.`Style` (`idStyle` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
To resume, the Genre tables references EntityType and Style, that's all.
The error occurs when I try to create a new Style and then add an association in the Genre table.
Everything is within a transaction, and what I do is:
create the new style in the Style table
get the id of the created style
insert an association in the genre table, and that's when I get the error.
I've searched quite a while on the web, but the only thing I found was this SO post: In MySQL, can I defer referential integrity checks until commit
I'm not sure this is what it is about here, because the error happens on a table that hadn't changed during the transaction (EntityType). Or am I missing something?
Can someone explain me the reason why I have this error please? (I'm stuck here)
Also, if it really have something to do with the SO post I mentioned earlier, is there a "clean" way of doing that kind of inserts without writing my own rollback mechanism?
Thanks for your answers
EDIT
the first query to insert a new style is:
CREATE PROCEDURE `Entity_CreateStyle`
(
IN p_name varchar(45),
OUT op_idStyle int(11)
)
BEGIN
insert into Style(idParentStyle, Name, IsValidated)
values(null, p_name, 0);
SET op_idStyle = LAST_INSERT_ID();
END
the next one, that produces the error:
CREATE PROCEDURE `Entity_AssociateStyleWithEntityType`
(
IN p_idGenre int(11),
IN p_Name varchar(45),
IN p_idEntityType int(11),
IN p_idStyle int(11)
)
BEGIN
insert into Genre(idGenre, Name, idEntityType, idStyle)
values(p_idGenre, p_Name, p_idEntityType, p_idStyle);
END
both are actually stored procedures that we call from C# using MySQL.Net connector
the p_idEntityType comes from the model (MVC) and I checked it's value is correct and exists in EntityType table.
The error message is clear: entitytype is referenced by genre. This means that ALL rows in entitytype must have a match in genre, or can't be inserted. There is a match when genre.entitytype = entitytype.entitytype.

Trying to Run a stored procedure in mySQL and it fails on a foreign key constraint

I wrote a simple Stored Procedure with a while loop that's not working.
Here's some data for you:
the parent table is data_client_id. The tables are all innoDB. The primary key is ID. All other tables in the schema with the data_ prefix have this (data_client_id.id) column as a foreign key.
I generated some dummy data and inserted it into the data_client_id table which auto-increments the primary key. The rows generated were 33 through 132. My intention was to write one stored procedure that would create rows with matching values in the id column for all of the other data_ tables.
Here is my code:
mysql> DELIMITER //
mysql> CREATE PROCEDURE this()
-> BEGIN
-> DECLARE v1 INT;
-> SET v1 = 33;
-> WHILE v1 < 132 DO
-> INSERT INTO data_banking (id) VALUES(v1);
-> SET v1 = v1+1;
-> END WHILE;
-> END//
Query OK, 0 rows affected (0.00 sec)
Then when I CALL the this(); Procedure I get the following error:
mysql> call this();
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`oms_clients`.`data_banking`, CONSTRAINT `data_banking_FK` FOREIGN KEY (`id`) REFERENCES `data_client_id` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
I tried just running standalone INSERTs into the data_ tables like this:
INSERT into data_banking (id) VALUES (34);
and it worked setting all the columns with defaults to NULL or their respective SET defaults...
There's nothing wrong with your stored procedure.
The problem is that you can't insert a run into data_banking unless the SAME id also exists in data_client_id. Each id, 33 through 132.
To fix the problem, remove the constraint, or make sure the foreign key dependency is resolved.
Here's a good link with some useful tips:
Mysql error 1452 - Cannot add or update a child row: a foreign key constraint fails

CanĀ“t INSERT values with Foreign Key in MySQL

I have a MySQL (5.1.42 on OsX) running.
I added a Foreign Key with this sql statement:
ALTER TABLE `Portal`.`Mitarbeiter_2_BlackBerry`
ADD CONSTRAINT `fk_Blackberry`
FOREIGN KEY (`id` )
REFERENCES `Portal`.`Blackberry` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION
, ADD INDEX `fk_Blackberry` (`id` ASC)
But when i try to insert values in that table with this sql statement:
INSERT INTO Mitarbeiter_2_BlackBerry SET uebergabeAm = '2009-12-01 13:00:00', fk_Blackberry = (SELECT id FROM Blackberry WHERE id = '1')
I got the following Error:
Error Code: 1054
Unknown column 'fk_BlackBerry' in 'field list'
Anybody an idea what could be wrong?
Thanks for any hint :-)
Lars.
You need to put the value in the column id not the constraint fk_Blackerry. And if you know the value is 1, just insert 1- you don't need the subquery.
As per the Syntax Which you you can refer from here.
http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
fk_Blackerry is Symbol, not the column. Column on which foreign key constraint is id, So the updated query should be
INSERT INTO Mitarbeiter_2_BlackBerry SET uebergabeAm = '2009-12-01 13:00:00', id = (SELECT id FROM Blackberry WHERE id = '1')