我可以在sqlite中插入触发器之前更新New in吗?

Posted

技术标签:

【中文标题】我可以在sqlite中插入触发器之前更新New in吗?【英文标题】:Can I update New in before insert trigger in sqlite? 【发布时间】:2012-02-20 05:52:29 【问题描述】:

例如:

create table test (id numeric, t date not null);

create trigger test_in
before insert on test
for each row
when New.t is null
begin
 -- set New.t = now();
end;

Set New.t 不起作用,where can be only select/insert/update/delete stmt. 我不能改变数据库结构(可以设置默认值)。 由于“非空”约束,插入触发器也不适合。 我找到的唯一解决方案:

insert into test values (New.id, now());
select raise(ignore);

测试数据库仅用于说明目的,在实践中还有更复杂的计算数据案例。可能有这种“update New set New.t = now()”之类的东西,还是没有?

【问题讨论】:

你能用 INSTEAD OF 触发器创建一个视图并插入到视图中吗? 这也是决定的变体,但不能解决问题。在我的情况下,表是在同步过程中创建的。之后我可以运行任何 ddl。 在主数据库模型中也使用了带 set stmt 的触发器。我可以创建视图,但必须更改和编程(如果可以的话……) 是的,选择 raise(ignore) 方法有效。 @Nico 这里好像删掉了一些cmets,能解释一下raise(ignore)的方法吗? 【参考方案1】:

不,您不能更新 NEW。

我倾向于使用带有 INSTEAD OF 触发器的 VIEW,因为 mu 是简短的注释。

在您的情况下,最好的解决方案可能是使用 AFTER INSERT/UPDATE 触发器 WHEN NEW.t IS NULL 来更新受影响行中的 t:

CREATE TRIGGER test_in
AFTER INSERT ON test
FOR EACH ROW
WHEN (NEW.t IS NULL)
BEGIN
   UPDATE test SET t = now() WHERE id = NEW.id;
END;

仅供参考,您的 id 列可能应该声明为 INTEGER PRIMARY KEY...

【讨论】:

我不适合这个选项,因为“not null”约束 - insert failed with null :( PS 新手不要混淆,最好使用 update ... where rowid = new.rowid跨度> 好吧,既然你有这个触发器 t 不会是 NULL,所以你可以放弃那个约束。至于rowid ......我暗示了这一点,但你是对的,新手可能不会得到暗示。另一方面,并​​不是所有的 RDBMS 总是有 rowid... 是的,SQLite3 基本上总是有一个 rowid,但是你可以有名为 rowid 的列不是整数主键,所以我觉得建议您使用明确的 INTEGER PRIMARY KEY 会更安全。

以上是关于我可以在sqlite中插入触发器之前更新New in吗?的主要内容,如果未能解决你的问题,请参考以下文章

在插入之前检查 sqlite 中的重复项(核心数据)

在多行插入语句 sqlite 上使用触发器

MS-ACCESS - 在插入之前/之后插入/更新触发器需要

我想在同一张表上创建更多触发器

创建计算每个新插入员工的总工资的行级触发器

MySQL触发器在插入或更新之前将日期值更改为weekstart