【问题标题】:Cannot insert row into table with foreign key field无法将行插入具有外键字段的表中
【发布时间】:2012-07-16 23:00:18
【问题描述】:

我正在开发一个广泛使用数据库的 PHP 应用程序。我设置数据库的同事设置表以使用外键。这是我正在使用的语句:

INSERT INTO patients (ethnicity, gender)
VALUES (1, 1);

INSERT INTO sessions (patient_id, submitted, age_in_years, video, annotated)
VALUES (LAST_INSERT_ID(), NOW(), 0, '', FALSE);

第一个语句有效。但是,第二个语句出现以下错误。

#1452 - 无法添加或更新子行:外键约束失败 (`/sessions`, CONSTRAINT `fk_sessions_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON更新级联时删除级联)

我已确认LAST_INSERT_ID() 返回预期值。

我该如何解决这个问题?

下面是我们如何设置sessions

CREATE TABLE IF NOT EXISTS `sessions` (
  `id` int(11) NOT NULL auto_increment,
  `patient_id` int(11) NOT NULL,
  `severity` enum('Minimal Symptoms of Autism Spectrum Disorder','Mild-to-Moderate Symptoms of Autism Spectrum Disorder','Severe Symtoms of Autism Spectrum Disorder') default NULL,
  `submitted` datetime default NULL,
  `age_in_years` int(11) NOT NULL,
  `video` text NOT NULL,
  `annotated` tinyint(1) default '0',
  PRIMARY KEY  (`id`),
  KEY `fk_sessions_1` (`patient_id`),
  KEY `age_in_years` (`age_in_years`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

ALTER TABLE `sessions`
  ADD CONSTRAINT `fk_sessions_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

编辑:删除了不必要的细节。如果您觉得需要更多,请随时查看这篇文章的第一个版本。

【问题讨论】:

  • 您是否验证过 LAST_INSERT_ID() 返回的 id 存在于“患者”表中?
  • 它返回0。任何想法为什么?
  • 您的连接字符串中是否将自动提交设置为 false?
  • 这可能完全不对,因为我根本不是 MySQL 专家(一般来说 SQL 也是如此),但这可能是因为您没有在第一条语句中指定 PK 吗?从参考资料来看,似乎 LAST_INSERT_ID() 从 AUTOINCREMENT 字段(通常是您的 PK)返回最后一个值。 dev.mysql.com/doc/refman/5.0/en/…
  • @Jeshurun,我在 SQL 语句之前调用$database->beginTransaction();,之后调用$database->commit();。我的 PHP 的其余部分在第一个版本中。

标签: mysql foreign-keys innodb


【解决方案1】:

事实证明,当我的同事添加外键时,他在外键引用的表名中有错字。

ALTER TABLE `sessions`
  ADD CONSTRAINT `fk_sessions_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

应该是

ALTER TABLE `sessions`
  ADD CONSTRAINT `fk_sessions_1` FOREIGN KEY (`patient_id`) REFERENCES `patients` (`id`) ON DELETE CASCADE;

【讨论】:

    【解决方案2】:

    错误告诉你究竟出了什么问题。

    您试图在sessons.patient_id 中插入一个在patients.id 中不存在的值。这就是外键约束的设计方式。无论 LAST_UPDATE_ID() 的值是否符合您的预期,您都需要在patients.id 中确认该值是否有效。

    例子:

    patients
    ---------------
    id    |    name
    ---------------
    1     |    john
    2     |    jane
    

    如果您尝试在sessions.patient_id 中插入“3”,您将收到您看到的错误,因为idpatients 中不存在。

    【讨论】:

      猜你喜欢
      • 2018-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多