外键约束在事务中失败

时间:2012-07-11 13:16:30

标签: php mysql transactions yii innodb

我正在使用PHP / MySQL + Yii Framework开发基于Web的应用程序。该问题作为事务中的约束检查错误发生。

我有以下表格:

用户

CREATE TABLE IF NOT EXISTS `User` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) DEFAULT NULL,
  `surname` varchar(64) DEFAULT NULL,
  `email` varchar(128) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `creation_date` datetime DEFAULT NULL,
  `last_login_date` datetime DEFAULT NULL,
  `status` tinyint(1) DEFAULT '0',
  `level` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=40 ;

CandidateInfo

CREATE TABLE IF NOT EXISTS `CandidateInfo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `candidate_status_id` int(11) DEFAULT NULL,
  `name` varchar(64) DEFAULT NULL,
  `surname` varchar(64) DEFAULT NULL,
  `email` varchar(128) DEFAULT NULL,
  `gender` tinyint(1) DEFAULT '0',
  `date_of_birth` datetime DEFAULT NULL,
  `home_phone` varchar(20) DEFAULT NULL,
  `mobile_phone` varchar(20) DEFAULT NULL,
  `creation_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `rating` tinyint(1) DEFAULT '0',
  `location` varchar(100)DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_candidateinfo_user` (`id`),
  KEY `FK_candidateinfo_candidatestatus` (`candidate_status_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=26 ;

基本上我正在尝试向用户表添加新行,然后使用插入ID将新行添加到 CandidateInfo 表(user_id列)

php代码为

$transaction = Yii::app()->db->beginTransaction();
try {
    $user->save();
    $candidate->setAttribute('user_id', $user->id);
    $candidate->save();
    $transaction->commit();
} catch (Exception $e) {
    $transaction->rollBack();
    var_dump($e->getMessage());
}

错误是:

 SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`origo`.`CandidateInfo`, CONSTRAINT `FK_candidateinfo_user` FOREIGN KEY (`id`) REFERENCES `User` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION). The SQL statement executed was: INSERT INTO `CandidateInfo` (`gender`, `rating`, `name`, `surname`, `email`, `date_of_birth`, `home_phone`, `mobile_phone`, `user_id`) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6, :yp7, :yp8)

当我检查mysql查询日志时,我看到它为CandidateInfo表的INSERT语句采用了正确的user_id。但由于上述错误而失败。从我的理解,它应该工作,但可能是我错了,这不是交易的工作方式。

这两个表都是InnoDB。

提前致谢。

修改 抱歉忘了粘贴FK关系。

ALTER TABLE `CandidateInfo`
  ADD CONSTRAINT `FK_candidateinfo_candidatestatus` FOREIGN KEY (`candidate_status_id`) REFERENCES `CandidateStatus` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  ADD CONSTRAINT `FK_candidateinfo_user` FOREIGN KEY (`id`) REFERENCES `User` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;

2 个答案:

答案 0 :(得分:3)

ALTER TABLE `CandidateInfo`
  ADD CONSTRAINT `FK_candidateinfo_candidatestatus` FOREIGN KEY (`candidate_status_id`) REFERENCES `CandidateStatus` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  ADD CONSTRAINT `FK_candidateinfo_user` FOREIGN KEY (`id`) REFERENCES `User` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;

应该是

ALTER TABLE `CandidateInfo`
  ADD CONSTRAINT `FK_candidateinfo_candidatestatus` FOREIGN KEY (`candidate_status_id`) REFERENCES `CandidateStatus` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  ADD CONSTRAINT `FK_candidateinfo_user` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;

你的id中有id id。

答案 1 :(得分:2)

您的错误堆栈:

  
    

SQLSTATE [23000]:完整性约束违规:1452无法添加或更新子行:外键约束失败(origoCandidateInfo,CONSTRAINT FK_candidateinfo_user FOREIGN KEY({{ 1}})参考idUser)ON更新没有动作更新无动作)。

         

执行的SQL语句是:

  
id

您的INSERT INTO `CandidateInfo` ( `gender`, `rating`, `name`, `surname`, `email`, `date_of_birth`, `home_phone`, `mobile_phone`, `user_id` ) VALUES ( :yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6, :yp7, :yp8 ) 表将CandidateInfo字段定义为id主键字段和外键。
并且您的auto_increment语句不包含insert,请从其父id表中读取 因此,在插入时,会为user表格生成 id值并应用。
哪个实习生失败,因为它与父candidateinfo表的任何主键id值都不匹配。

因此是错误。

注意
在子表中,如果您将主服务器的pk字段称为外键字段,则 你不应该为它申请user,而只是参考。


仔细查看auto_increment结构,我觉得您可能希望将candidateinfo映射到use_id字段。使用适当的外键定义进行更改可以解决您的问题。