[英]ASP.NET: Cannot add or update child row: a foreign key constraint fails
i have a strange issue in a asp.net application. 我在asp.net应用程序中有一个奇怪的问题。 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
我有两个表保存一些变量更改的历史记录,一个带有另一个外键,但是由于某种原因,mysql插入第二个表时会抛出错误
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. 我尝试用
@@identity
替换last_insert_id()
,但也没有用。 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. 代码中存在SQL注入问题的一部分,此行为的可能原因是
db
变量。 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. 如果此变量是每次调用ExecuteXXX方法都会打开和关闭连接的自定义类的某个实例,那么您可能会遇到
SELECT LAST_INSERT_ID
的问题,该问题与将值插入第一个表的连接不同。
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. 这样,您仅执行一条命令,并且应确保将SELECT last_insert_id()的返回值有效地设置为当前的插入命令。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.