我能在MySQL的select语句上启动触发器吗?

26
我想在从表Y选择任何记录时,在表X上运行一个INSERT语句,有没有使用仅限于MySQL的方法来实现这一点?类似于触发器吗?

2
简短的答案是不行。触发器会在INSERTUPDATEDELETE时被触发。 - ypercubeᵀᴹ
对于批量操作,更新每一行的选择会导致性能问题。最好是针对有意义的操作专门更新last_accessed时间戳。 - Jeff Lowery
3个回答

34

简短的答案是不行。触发器只有在进行INSERTUPDATEDELETE操作时才会被触发。

以下是针对这种罕见情况的可能解决方案:

  • 首先编写一些存储过程,用于在表X上执行您想要的SELECT操作。
  • 然后,限制所有用户仅使用这些存储过程,并且不允许他们直接在表X上使用SELECT
  • 然后修改存储过程,以便它也调用执行所需操作(例如INSERT)的存储过程。

1
我想对“奇怪”的描述提出异议。具体来说,如果我们正在访问受控信息(例如制造标签),我们希望控制存储在数据库中的文档被访问或打印的次数,那么这正是我想要的功能。 如果信息控制是错误的(“奇怪”),那我宁愿错。 - Danny Holstein
1
@DannyHolstein 好的,“奇怪”不是最好的选择。用“罕见”听起来更好吗? - ypercubeᵀᴹ
我应该提出一个功能请求来实现这个能力。 - Danny Holstein
我尝试使用VIEW和存储函数实现解决方案,但在尝试向跟踪访问的表中插入数据时,由于该表已经打开并被锁定,因此无法进行插入操作。 - Danny Holstein
@DannyHolstein,您可以发布一个新问题,附上您的实现和出现的问题(并添加到此问题的链接)。 - ypercubeᵀᴹ

5

不行 - 你不能对SELECT触发器进行触发 - 你必须创建一个存储过程(或任何其他类型的日志记录设施 - 如日志文件或任何其他设备),在任何查询语句上隐式调用它 - 如果你创建一个调用查询、调用日志记录并返回查询结果的包装器,会更容易。


2
如果您想使用表X记录对表Y的 SELECT 查询顺序(这是一个相当常见的查询记录设置),可以简单地颠倒操作顺序并先运行 INSERT 查询,然后再运行 SELECT 查询。这样,您就不需要担心使用 TRIGGER 将两个语句链接起来:如果服务器在两个语句之间崩溃,则您已经使用第一个语句记录了您所关心的内容,并且无论 SELECT 查询是否运行或失败,都不会影响底层数据库。
如果您没有记录查询,也许您正在尝试使用Y表作为任务队列 - 这是我困扰的情况,导致我找到了这个线程 - 并且您希望先查询Y的会话锁定所有其他会话以防止返回的行,以便您可以对结果执行某些操作并将输出插入表X。在这种情况下,只需向表Y添加一些日志功能即可。
例如,您可以向Y表添加一个“所有者”列,然后将 SELECT 查询的 WHERE 部分附加到 UPDATE 语句上,运行它,然后修改 SELECT 查询以仅显示由 UPDATE 声明的结果。
UPDATE Y SET owner = 'me' WHERE task = 'new' AND owner IS NULL;
SELECT foo FROM Y WHERE task = 'new' AND owner = 'me';

...do some work on foo, then...

INSERT INTO X (output) VALUES ('awesomeness');

关键是先记录日志,然后再查询。


有点像,但我受限于使用多行。这是一个愚蠢的打印机驱动程序,只会查看视图。我确实想出了一种解决方案,可以按计划间隔撤销条目,但我发现Bradly打印机软件中存在更多的错误,使其完全无法使用,而且那里没有人想修复它。 - Danny Holstein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接