试图将外键与触发器结合起来

Posted

技术标签:

【中文标题】试图将外键与触发器结合起来【英文标题】:trying to combine foreign key with trigger 【发布时间】:2013-10-06 22:23:09 【问题描述】:

删除某些行和关系后,我无法清理数据库。

CREATE TABLE IF NOT EXISTS `cms_users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(50) DEFAULT NULL,
  `last_name` varchar(50) DEFAULT NULL,
  `id_account_type` smallint(2) unsigned NOT NULL,
  PRIMARY KEY (`id`)
);

以上是一些用户。这些用户有孩子,他们存储在其他表中:

CREATE TABLE IF NOT EXISTS `cms_users_relations` (
  `id_user` int(10) unsigned NOT NULL,
  `id_parent` int(10) unsigned DEFAULT NULL,
  UNIQUE KEY `id_user` (`id_user`),
  KEY `constraint_9` (`id_parent`)
);


ALTER TABLE `cms_users_relations`
  ADD CONSTRAINT `constraint_8` FOREIGN KEY (`id_user`) REFERENCES `cms_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `constraint_9` FOREIGN KEY (`id_parent`) REFERENCES `cms_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

问题是,当我从 cms_users 中删除父级时,所有子级也应该被删除,但他们没有。我为此目的创建了一个触发器,但它不起作用:

DELIMITER //
CREATE TRIGGER `delete_user` AFTER DELETE ON `cms_users_relations`
 FOR EACH ROW BEGIN 
  DELETE FROM cms_users WHERE OLD.id_user = cms_users.id; 
 END
//
DELIMITER ;

看起来mysql服务器不打扰我们删除用户,然后通过外键删除关系,然后我们应该放置触发器......

有什么想法吗?

【问题讨论】:

SQL 只是 结构化查询语言 - 许多数据库系统使用的语言,但不是数据库产品...很多事情都是特定于供应商的 - 所以我们真的需要知道您正在使用什么数据库系统(以及哪个版本)(请相应地更新标签)...... 我同意,我知道,但我忘了说明。 【参考方案1】:

该触发器应该在cms_users 表上创建,而不是在cms_users_relations 上创建,然后在cms_users_relations 上删除,如下所示:

DELIMITER //
CREATE TRIGGER `delete_user` AFTER DELETE ON `cms_users`
 FOR EACH ROW BEGIN 
  DELETE FROM cms_users_relations WHERE OLD.id_user = cms_users_relations.id; 
 END
//
DELIMITER ;

trigger 是您在 cms_users 中对父级所做的删除,因此您要在此处创建它。


我只查看了您如何创建触发器,但错过了您所做的部分:

ALTER TABLE `cms_users_relations`
  ADD CONSTRAINT `constraint_8` FOREIGN KEY (`id_user`) REFERENCES `cms_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `constraint_9` FOREIGN KEY (`id_parent`) REFERENCES `cms_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

使用它,您不需要创建触发器来删除 cms_users 关系上的元素。

请参阅 this fiddle 以查看它的工作原理。

您可能想看看at the answers on this question,看看您可能有什么不同,这不起作用。

【讨论】:

我已经添加了触发器,检查我的引擎是否设置为 MyISAM 并且仍然无法工作:(当我删除父级时,子级仍然存在...... @PAM 。从我链接的问题来看,我认为你应该拥有引擎 InnoDB,而不是 MyISAM 才能工作。 当然我有 ENGINE=InnoDB DEFAULT CHARSET=utf8。对不起,这是一个错误。 MyISAM 不支持外键。 @PAM 。使用 ENGINE=InnoDB 和您创建 FOREIGN KEYS 的方式,您不需要触发器。只需卸下触发器,然后重试。如果它不起作用,请尝试使用您拥有的一些示例数据创建一个小提琴。 @PAM。另一件事。您在 cms_users 上的 id 为 int(11) ,在第二个表上为 int(10) 。它们在两个表中应该具有相同的类型。

以上是关于试图将外键与触发器结合起来的主要内容,如果未能解决你的问题,请参考以下文章

将外键传递给 Rails 中的部分渲染

将外键添加到迁移(Laravel)

SQL将外键添加到现有列

将外键放入表单

Laravel - 如何将外键用于具有识别外键的表?

[学习笔记]--数据库系统