【问题标题】:MYSQL UPDATE Table on INSERT into same tableMYSQL UPDATE 表上 INSERT 到同一个表
【发布时间】: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 我想我需要第二张桌子。

标签: mysql triggers database-trigger insert-update mysql-error-1442


【解决方案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 错误。我想我需要第二张桌子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2014-09-09
    相关资源
    最近更新 更多