【问题标题】:Sqlite running update in insert trigger to execute update triggerSqlite 在插入触发器中运行更新以执行更新触发器
【发布时间】:2021-10-13 23:38:49
【问题描述】:

使用 sqlite,我希望在插入和更新时使用触发器从给定的“id”生成一个字段“url”。例如id: '1' => url: 'test.com/1'

表格如下所示:

CREATE TABLE t1 (
  id TEXT,
  url TEXT
 );

由于 sqlite 无法为更新和插入运行相同的触发器,因此我看到了两个选项来完成此操作。

选项 A

  • 插入后运行触发器,将 id 更新为自身,进而触发更新触发器
CREATE TRIGGER run_updates_on_insert AFTER INSERT ON t1
  BEGIN
    UPDATE t1 SET id = NEW.id WHERE id = NEW.id;
  END;

CREATE TRIGGER set_url_on_update BEFORE UPDATE on t1
  BEGIN
   UPDATE t1 SET url = 'test.com/' || NEW.id WHERE id = OLD.id;
  END;

选项 B

  • 在两个单独的触发器中复制逻辑以进行更新和插入
CREATE TRIGGER set_url_on_insert AFTER INSERT on t1
  BEGIN
   UPDATE t1 SET url = 'test.com/' || NEW.id WHERE id = NEW.id;
  END;

CREATE TRIGGER set_url_on_update BEFORE UPDATE on t1
  BEGIN
   UPDATE t1 SET url = 'test.com/' || NEW.id WHERE id = OLD.id;
  END;

这两个选项都给了我想要的结果,我倾向于选择选项 A,因为我只需要编写一次更新逻辑,但我想知道是否有任何其他优点/缺点更喜欢另一个?

编辑:对于这个特定的用例,最好使用生成的列(请参阅下面的 forpas 答案)

【问题讨论】:

  • 你的 SQLite 版本是多少?
  • Sqlite 版本:3.36.0

标签: sql sqlite triggers insert sql-update


【解决方案1】:

从 SQLite 3.31.0 (2020-01-22) 版本开始,您可以创建generated columns(存储或虚拟),因此您不需要任何触发器:

CREATE TABLE t1 (
  id TEXT,
  url TEXT GENERATED ALWAYS AS ('test.com/' || id) STORED
 );

【讨论】:

  • 谢谢,这确实解决了我的特殊问题!但是,如果其他人遇到这个问题,我不会将其标记为正确答案,因为它更多是一种解决方法以及如何最好地将插入与更新触发器结合起来的问题,可能在这种情况之外有用.
  • @react-newbie 在编程语言或方言中引入的每一个新特性都不是一种变通方法,而是一种解决常见问题的方法,而其他变通方法则用于解决这些问题。触发更新触发器的插入触发器是一种解决方法。执行相同代码的插入触发器和更新触发器是一种解决方案,但不再适用。因此,在解决方法、旧解决方案和新的适当解决方案之间进行选择时,选择是显而易见的。
  • 当然,我并没有质疑你的建议是否有用,我实际上会这样使用它。但是,假设其他人发现了问题,并且他想在更新和插入时运行触发器,从而在不同的表中创建一个日志条目。在他的情况下,答案对他没有帮助。
  • @react-newbie 当其他人搜索“触发器”时,他们会找到数百个线程。如果他们正在寻找“如何在不同的表中创建日志条目”,那么他们将通过,因为要求不同。您的问题是关于创建一个计算列,而您尝试的是触发器,它有效。我的回答是关于一些新的和更好的东西。您希望我建议选项 A 或选项 B 吗?这两个选项都已过时。
猜你喜欢
  • 2014-09-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多