如何修复错误1452和正确关联表

时间:2019-06-06 08:00:17

标签: mysql

我正在创建一个在线考试系统。在数据库中,我似乎无法正确关联我的表并导致遇到错误。当我将数据提交到tbl_choices表时,出现错误1452。您知道该怎么办吗?

我尝试在sql和关系视图中执行它,但似乎不起作用。我还观看了一些有关使用外键创建表和更改表的视频。

tbl_qtopic

tbl_question

tbl_choices

tbl_qtopic:

CREATE TABLE `tbl_qtopic` (
  `topic_id` int(11) NOT NULL,
  `topic_name` varchar(255) CHARACTER SET latin1 NOT NULL,
  `description` varchar(255) CHARACTER SET latin1 NOT NULL,
  `date_created` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

tbl_question:

CREATE TABLE `tbl_question` (
  `ques_id` int(11) NOT NULL,
  `topic_id` int(11) NOT NULL,
  `ques` varchar(255) CHARACTER SET latin1 NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `tbl_question`
  ADD CONSTRAINT `fk_question` FOREIGN KEY (`topic_id`) REFERENCES `tbl_qtopic` (`topic_id`) ON DELETE NO ACTION ON UPDATE CASCADE;
COMMIT;

tbl_choice:

CREATE TABLE `tbl_choices` (
  `ch_id` int(11) NOT NULL,
  `ques_id` int(11) NOT NULL,
  `ques` varchar(255) CHARACTER SET latin1 NOT NULL,
  `ch_des1` varchar(255) CHARACTER SET latin1 NOT NULL,
  `ch_des2` varchar(255) CHARACTER SET latin1 NOT NULL,
  `ch_des3` varchar(255) CHARACTER SET latin1 NOT NULL,
  `ch_des4` varchar(255) CHARACTER SET latin1 NOT NULL,
  `ans` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `tbl_choices`
  ADD CONSTRAINT `fk_choices` FOREIGN KEY (`ques_id`) REFERENCES `tbl_question` (`ques_id`) ON DELETE NO ACTION ON UPDATE CASCADE;

这是错误消息。

Error Number: 1452

Cannot add or update a child row: a foreign key constraint fails (`examsystem`.`tbl_choices`, CONSTRAINT `fk_choices` FOREIGN KEY (`ques_id`) REFERENCES `tbl_question` (`ques_id`) ON DELETE NO ACTION ON UPDATE CASCADE)

INSERT INTO `tbl_choices` (`ques`, `ch_des1`, `ch_des2`, `ch_des3`, `ch_des4`, `ans`) VALUES ('What does \'SQL\' stands for?', 'Super Query Language', 'Standard Query Language', 'Structured Query Language', 'Structured Question Language', '3')

1 个答案:

答案 0 :(得分:0)

外键基本上说,在引用表(父表)中,对于具有外键的表(子表)中的每个条目,都需要有一个条目。可以这么说,它可以防止没有父母的孩子。

这意味着您必须以正确的顺序插入,在这种情况下,首先需要在tbl_qtopic中有一个条目,可以在tbl_question中进行引用。然后您在inserttbl_question,以便可以在tbl_choices中引用此条目。

要轻松完成此操作,您应该有一个主键,它也是一个auto_increment列。另请注意,您应该始终在表中具有主键。

您的表应如下所示:

CREATE TABLE `tbl_qtopic` (
  `topic_id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `topic_name` varchar(255) CHARACTER SET latin1 NOT NULL,
  `description` varchar(255) CHARACTER SET latin1 NOT NULL,
  `date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `tbl_question` (
  `ques_id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `topic_id` int(11) NOT NULL,
  `ques` varchar(255) CHARACTER SET latin1 NOT NULL,
  CONSTRAINT `fk_question` FOREIGN KEY (`topic_id`) REFERENCES `tbl_qtopic` (`topic_id`) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

然后,您只需在事务中插入即可。事务捆绑了多个语句,因此,如果一个语句失败,则该事务中的所有语句都将被撤消(回滚)。每次插入后,您都保存在auto_increment列中生成的id,并将此值用于下一个insert语句。

注意,这只是MySQL代码。您必须查看如何使用PHP或自己使用的工具。我是数据库管理员,不是程序员:)

START TRANSACTION;
INSERT INTO tbl_qtopic (topic_name, description) VALUES ('foo', 'bar');
SELECT LAST_INSERT_ID(); /* store this value in a variable */
INSERT INTO tbl_question (topic_id, ques) VALUES (<the value from above select>, 'baz');
COMMIT;

我猜你明白了。请注意,您不需要auto_increment语句中的insert列。这些值将自动生成。在此示例中,我故意省略了表tbl_choices,因为它需要重新设计。 ch_des没有几列(我猜是“选择说明”吗?)。那是不好的设计。如果一个问题有5个选择怎么办?如果一个人只有3个怎么办?是否添加一列,并在某些列中包含几行具有NULL值的行?使那些列行。您无需在表之间强制建立1:1关系。阅读有关数据库规范化的知识! ans列应该是问题的正确答案?它可能不应该在此表中,特别是当您选择一个问题作为行而不是列时。表的设计是一个巨大的话题,在这个问题上有太多的答案无法解决。如果您需要帮助,请打开另一个问题。

最后,一些适合您的文献: