繁体   English   中英

ASP.NET:无法添加或更新子行:外键约束失败

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

我在asp.net应用程序中有一个奇怪的问题。 我有两个表保存一些变量更改的历史记录,一个带有另一个外键,但是由于某种原因,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`))

这是使插入到两个表中的代码(假定局部变量具有值)。 我在本地进行了测试,但是当我在生产环境中安装该站点时,会引发上述错误。

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);
}

这是表定义。

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;

我尝试用@@identity替换last_insert_id() ,但也没有用。 我尝试直接将查询执行到数据库中,并且工作正常。

代码中存在SQL注入问题的一部分,此行为的可能原因是db变量。 如果此变量是每次调用ExecuteXXX方法都会打开和关闭连接的自定义类的某个实例,那么您可能会遇到SELECT LAST_INSERT_ID的问题,该问题与将值插入第一个表的连接不同。

您可以尝试合并两个初始命令,以使它们由同一连接一起处理

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);

这样,您仅执行一条命令,并且应确保将SELECT last_insert_id()的返回值有效地设置为当前的插入命令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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