简体   繁体   中英

ASP.NET: Cannot add or update child row: a foreign key constraint fails

i have a strange issue in a asp.net application. I have two tables who save history of some variable changes, one with a foreign key to the other, but for some reason, mysql throws error while inserting to the second table

Cannot add or update a child row: a foreign key constraint fails (`FlowDB/tab_hist_vars_reas`, CONSTRAINT `tab_hist_vars_reas_ibfk_1` FOREIGN KEY (`HIST_REASIG_ID`) REFERENCES `tab_hist_reas` (`HIST_REASIG_ID`))

This is the code that makes the insert into the two tables (assume that local variables have values). I tested locally but when i install the site in the production environment it throws the above error.

string strcmd = "INSERT INTO tab_hist_reas (HIST_REASIG_INC,HIST_REASIG_FLOW,HIST_REASIG_STEP,HIST_REASIG_DATE,HIST_REASIG_USER)";
strcmd += string.Format("VALUES ({0}, '{1}', '{2}', NOW(), '{3}');", incident, flow, step, user);
db.executeNonQuery(strcmd);

strcmd = "SELECT last_insert_id() AS id";
int idHistory = (int)db.ExecuteScalar(strcmd);

foreach(var variable in lstVariables)
{
    string strcmd = "INSERT INTO tab_hist_vars_reas (HIST_REASIG_ID,HIST_VAR_REASIG_VAR,HIST_VAR_REASIG_VALUE)";
    strcmd += string.Format("VALUES ({0}, '{1}', '{2}');", idHistory, variable.Name, variable.Value);
    db.executeNonQuery(strcmd);
}

Here are the table definitions.

CREATE TABLE `tab_hist_reas` (
`HIST_REASIG_ID` int(11) NOT NULL auto_increment,
`HIST_REASIG_INC` int(11) default NULL,
`HIST_REASIG_FLOW` varchar(150) default NULL,
`HIST_REASIG_STEP` varchar(150) default NULL,
`HIST_REASIG_DATE` datetime default NULL,
`HIST_REASIG_USER` varchar(150) default NULL,
PRIMARY KEY  (`HIST_REASIG_ID`)
) ENGINE=InnoDB;

CREATE TABLE `tab_hist_vars_reas` (
`HIST_VAR_REASIG_ID` int(11) NOT NULL auto_increment,
`HIST_REASIG_ID` int(11) NOT NULL,
`HIST_VAR_REASIG_VAR` varchar(100) default NULL,
`HIST_VAR_REASIG_VALUE` varchar(100) default NULL,
PRIMARY KEY  (`HIST_VAR_REASIG_ID`),
KEY `IND_HIST_VAR_REAS_ID_HIST` (`HIST_REASIG_ID`),
CONSTRAINT `tab_hist_vars_reas_ibfk_1` FOREIGN KEY (`HIST_REASIG_ID`) REFERENCES `tab_hist_reas` (`HIST_REASIG_ID`)
) ENGINE=InnoDB;

I tried replacing the last_insert_id() with @@identity but didn't work either. I tried executing the query directly into the database and it works fine.

A part from the Sql Injection problem that you have in your code, a probable reason for this behavior is the db variable. If this variable is some instance of a custom class that opens and closes the connection every time you call an ExecuteXXX method then you could face a problem with the SELECT LAST_INSERT_ID called in a different connection from the one that inserts the values in the first table.

You could try to merge the two initial commands to have them handled together by the same connection

string strcmd = @"INSERT INTO tab_hist_reas 
                  (HIST_REASIG_INC,HIST_REASIG_FLOW,HIST_REASIG_STEP,
                  HIST_REASIG_DATE,HIST_REASIG_USER) ";
strcmd += string.Format("VALUES ({0}, '{1}', '{2}', NOW(), '{3}');", incident, flow, step, user);
strcmd += "SELECT last_insert_id() AS id";
int idHistory = (int)db.ExecuteScalar(strcmd);

In this way you exec just one command and you should be sure that the return from the SELECT last_insert_id() is effectively set to the current insert command.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM