MYSQL UPDATE 表上 INSERT 到同一个表
Posted
技术标签:
【中文标题】MYSQL UPDATE 表上 INSERT 到同一个表【英文标题】:MYSQL UPDATE Table on INSERT into same table 【发布时间】:2020-09-03 01:22:14 【问题描述】:这看起来很简单,但仍然是一个挑战。我尽可能简化了我的问题。
我有这个带有一条记录的 test_table:
id | cost_per_record
1 | 24
在 INSERT 之后,我希望表格如下所示:
id | cost_per_record
1 | 12
2 | 12
从我工作的应用程序中,我无法调用存储过程,所以我使用的代码:
DROP TABLE IF EXISTS `test_table`;
CREATE TABLE `test_table` (
`id` int(11) NOT NULL,
`cost_per_record` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `test_table` (`id`, `cost_per_record`) VALUES (1,24);
DELIMITER $$
CREATE TRIGGER `test_insert` BEFORE INSERT ON `test_table` FOR EACH ROW
BEGIN
update `test_table` set `cost_per_record` = 12
where `id` = 1;
END
$$
DELIMITER ;
INSERT INTO `test_table` (`id`, `cost_per_record`) VALUES
(2,12);
我通常收到的错误(在其他尝试中也是如此):
mysql said: Documentation
#1442 - Can't update table 'kan_test_update' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
相信我,我在这个论坛上阅读了很多答案,还跑到博客上说这是impossible。但我(仍然)不接受这一点。所以..任何解决方案...谢谢...
【问题讨论】:
开始时有 2 条或更多条记录会怎样?你的要求有点不寻常。 '但我(仍然)不接受这个' - 你应该。顺便说一句,在插入触发器之前,您可以调整 NEW 的值。柱子。详情请阅读dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html。 您要解决什么问题?也许替代设计更适合您的场景 正如我所说,我尽可能简化了我的问题,我只想在插入之后或之前更新同一张表中的其他记录 谢谢@P.Salmon 我想我需要第二张桌子。 【参考方案1】:对我来说,现在下面的解决方案有效,所以使用第二个表。我添加了一些智能,因此添加第三条记录会将成本从 12 -> 8 降低。我用它来为从同一餐组订购更多餐点的人提供折扣。这仍然是一种解决方法,而不是最初的问题,但是嘿。谢谢大家,谁回复了。
DROP TABLE IF EXISTS `test_table`;
DROP TABLE IF EXISTS `sub_table`;
CREATE TABLE `test_table` (
`id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `sub_table` (
`id` int(11) NOT NULL,
`cost_per_record` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `test_table` (`id`) VALUES (1);
INSERT INTO `sub_table` (`id`, `cost_per_record`) VALUES (1,24);
DELIMITER $$
CREATE TRIGGER `test_insert` AFTER INSERT ON `test_table` FOR EACH ROW
BEGIN
UPDATE `sub_table` set `cost_per_record` = (24/(SELECT COUNT(*) FROM `test_table`)) ;
INSERT INTO `sub_table` (`id`, `cost_per_record`) VALUES (NEW.ID,(24/(SELECT COUNT(*) FROM `test_table`)));
END
$$
DELIMITER ;
INSERT INTO `test_table` (`id`) VALUES (2);
INSERT INTO `test_table` (`id`) VALUES (3);
SELECT * from `sub_table`;
【讨论】:
【参考方案2】:像下面这样的触发器只能改变当前插入的行。
DELIMITER $$
CREATE TRIGGER `test_insert` BEFORE INSERT ON `test_table` FOR EACH ROW
BEGIN
IF NEW.`id` = 1 THEN
SET NEW.`cost_per_record` = 12;
END IF;
END
$$
DELIMITER ;
要更新其他行并插入,只能使用存储过程。
喜欢
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `new_procedure`( IN _id Integer, IN _Value INTEGER)
BEGIN
IF _id > 1 THEN
UPDATE test_table SET `cost_per_record` = 12 WHERE id = 1;
END IF;
INSERT INTO `test_table` (`id`, `cost_per_record`) VALUES
(_id,_value);
END$$
DELIMITER ;
并使用
DROP TABLE IF EXISTS `test_table`;
CREATE TABLE `test_table` (
`id` int(11) NOT NULL PRIMARY KEY,
`cost_per_record` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `test_table` (`id`, `cost_per_record`) VALUES (1,24);
call new_procedure(2,12);
SELECT * FROM test_table;
插入新行 或者你找到另一种可以使用触发器的算法,因此不涉及同一张表
Triggers有很多限制,所以当你尝试制作新系统时应该记住这一点
【讨论】:
谢谢,但是更改为该代码会在我的表中给出以下结果:id | cost_per_record 1 | 24 2 | 12 记住我在第一次插入后添加了触发器,第二次插入应该更新第一条记录 @Frits Nagtegaal 您的最后一条评论没有在您的问题中解释,id 2 更新 id 1 的逻辑是什么以及将 id 1 设置为的金额的逻辑是什么? @FritsNagtegaal 我更新了我的答案,这是无法解决的,而是使用一个程序 @nbk 谢谢,但正如请求中所述,“从我工作的应用程序中,我无法调用存储过程”。我可以像你描述的那样在触发器中调用一个 SP,但这会产生相同的 1442 错误。我想我需要第二张桌子以上是关于MYSQL UPDATE 表上 INSERT 到同一个表的主要内容,如果未能解决你的问题,请参考以下文章
MySQL INSERT 在同一张表上使用带有 COUNT() 的子查询