我正在创建一个在线考试系统。在数据库中,我似乎无法正确关联我的表并导致遇到错误。当我将数据提交到tbl_choices表时,出现错误1452。您知道该怎么办吗?
我尝试在sql和关系视图中执行它,但似乎不起作用。我还观看了一些有关使用外键创建表和更改表的视频。
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')
答案 0 :(得分:0)
外键基本上说,在引用表(父表)中,对于具有外键的表(子表)中的每个条目,都需要有一个条目。可以这么说,它可以防止没有父母的孩子。
这意味着您必须以正确的顺序插入,在这种情况下,首先需要在tbl_qtopic
中有一个条目,可以在tbl_question
中进行引用。然后您在insert
中tbl_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
列应该是问题的正确答案?它可能不应该在此表中,特别是当您选择一个问题作为行而不是列时。表的设计是一个巨大的话题,在这个问题上有太多的答案无法解决。如果您需要帮助,请打开另一个问题。
最后,一些适合您的文献: