【问题标题】:Why is this BEFORE INSERT trigger not working in MySQL?为什么这个 BEFORE INSERT 触发器在 MySQL 中不起作用?
【发布时间】:2014-05-27 02:34:05
【问题描述】:

我有一个名为 Base52Encode 的 MySql 函数,它接受一个 bigint 并返回一个 varchar(12)。

我有一个名为 Things 的表,它有一个 bigint auto_increment 作为主键,称为 ThingId,还有一个 varchar(12) 类型的第二列,称为 ShortCode。

我想将 ShortCode 的值设置为通过 auto_increment 创建的 ThingId 主键的 base-52 编码值。

DELIMITER $$

CREATE TRIGGER BeforeInsertThings
BEFORE INSERT ON Things 
FOR EACH ROW

BEGIN

    set new.ShortCode = Base52Encode(new.ThingId);

END $$

但是每当我插入一行时,ShortCode 值总是设置为 0(零),这意味着传递给 Base52Encode 的值也是零。

我假设问题是当此触发器运行时 auto_increment 值尚未启动。

那么我该如何解决这个问题呢?

【问题讨论】:

标签: mysql sql triggers


【解决方案1】:

试试这个

DELIMITER $$

CREATE TRIGGER BeforeInsertThings
BEFORE INSERT ON Things 
FOR EACH ROW

BEGIN
    Select ThingId into largestId order by ThingId Desc limit 1;
    Set newThingId = largestId + 1;
    set new.ShortCode = Base52Encode(newThingId);

END $$

【讨论】:

  • 有趣的解决方法,但是否有可能同时发生两个插入,导致 ShortCode 设置为完全相同的值(因为两个插入触发器会看到相同的最大 ID )?
【解决方案2】:

我假设它不起作用的原因是,当您插入一行时,您没有指定主键,因为您希望它只是自动递增。因此,您没有 new.ThingId 值。您可以使用AFTER INSERT 而不是BEFORE INSERT 轻松解决此问题:

DELIMITER $$

CREATE TRIGGER AfterInsertThings
AFTER INSERT ON Things 
FOR EACH ROW

BEGIN

    set new.ShortCode = Base52Encode(old.ThingId);
    # Or, you could use:
    # set new.ShortCode = Base52Encode(last_insert_id());

END $$

【讨论】:

  • 当我尝试在 AFTER INSERT 中执行此操作时,它告诉我无法编辑触发器中当前正在操作的表(我想避免循环引用)。
【解决方案3】:

正如this similar question on SO 中所解释的,在 MySQL 中的触发器上下文中,我想要做的事情是不可能的,唯一的解决方案是做我已经在做的事情来解决这个问题:处理需要的额外逻辑在我的存储过程中的现有 INSERT 代码之后直接运行。不理想,但就是这样。

【讨论】:

  • 您复制我的(我的链接)添加自己的答案,并将其标记为好答案。这不公平。您已经在我的问题 cmets 中解释了这个解决方案。如果您开始赏金,人们会为您提供解决方案的方法,至少希望得到认可。
  • @CedricSimon 我完全计划在 SO 允许后至少给你一些赏金信用。但是,您的一半“答案”只是错误地责备我发帖,而另一半只是与 SO 上的另一个问题相关联,而没有明确回答我的问题。我将我的后续行动标记为答案的原因是因为它为以后遇到这个问题的新人提供了一切。 Flat out:我想做的事情在触发器中是不可能的,唯一的解决方案是在外部处理逻辑。如果您的回答说明了这一点,我会将其标记为答案。
【解决方案4】:

这个问题似乎与this question 重复。

根据this question,插入后设置自动增量。因此,不要指望 new.field 值在之前的触发器中为您检索它。

您应该在发布问题之前更好地搜索现有问题:S。

如果您的问题不是关于新功能或新软件/硬件,那么很有可能已经在本网站上超过 600 万个问题中提出并回答了...

【讨论】:

  • 嗨@CedricSimon。感谢您的建议,但实际上我在发布到 SO 之前总是进行大量搜索。由于我最初发布时不知道这个问题与 MySQL 中的自动增量工作原理有关,所以我怎么会提出你提到的关于自动增量的问题?
  • 据我了解,您想要对尚未设置的值进行编码。在链接的问题中提出了解决方法。
  • 是的,我通读了链接,似乎有两个建议的解决方法。一个基本上是@AshrafBashir 在这个问题中提出的答案,但我担心那里存在竞争条件,可能会同时插入多个记录,无论是由相同用户还是不同用户。另一个解决方法基本上是我已经在做的:在我的存储过程中,执行插入,然后立即执行我希望在触发器本身中执行的添加工作。我会发布一个明确的答案。
猜你喜欢
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
相关资源
最近更新 更多