使用SQLite触发器强制显式设置列值

问题描述 投票:2回答:1

是否有可能在SQLite3中声明一个触发器,该触发器强制用户在UPDATE语句中明确提供一个值?

假设我们有一个Article表:

CREATE TABLE Article (
  Id           INTEGER  PRIMARY KEY,
  Title        TEXT NOT NULL UNIQUE,
  Content      TEXT,
  UserInserted TEXT NOT NULL,
  UserUpdated  TEXT
);

我可以声明以下触发器,该触发器禁止列UserUpdated的空值:

CREATE TRIGGER IF NOT EXISTS Trig_Article_BEFORE_UPDATE
  BEFORE UPDATE OF Title, Content ON Article
BEGIN
  SELECT
  CASE
    WHEN new.UserUpdated IS NULL THEN RAISE(ABORT, 'UserUpdated must not be NULL.')
    WHEN length(new.UserUpdated) = 0 THEN RAISE(ABORT, 'UserUpdated must not be NULL.')
  END;
END;

插入效果正常:

INSERT INTO Article(Title, Content, UserInserted) VALUES('Foo', '', '<user_A>');

首先不提供UserUpdated的更新也可以:

UPDATE Article SET Content = 'Bar' WHERE Id = 1;
-- Error: UserUpdated must not be NULL.

UPDATE Article SET Content = 'Bar', UserUpdated = '' WHERE Id = 1;
-- Error: UserUpdated must not be NULL.

但是一旦设置了UserUpdated,就不再需要显式提供该列。

UPDATE Article SET Content = 'Bar', UserUpdated = '<user_B>' WHERE Id = 1;
UPDATE Article SET Content = 'Foo Bar' WHERE Id = 1;
-- No error

是否有一种声明触发器的方法,以便最后一条语句也引发错误?

database sqlite triggers
1个回答
0
投票

使用另一个仅更新列。这是涉及内容的简要概述:

  • 向表添加“仅更新”列:UserUpdateONLY
  • 在BEFORE UPDATE触发器上,要求New.UserUpdateONLY IS NOT NULLNew.UserUpdated != Old.UserUpdated避免两列都与更新数据相矛盾(如果任一条件为假,则引发错误。)>
  • 在INSTEAD OF UPDATE触发器上,将值从仅更新列复制到普通存储列:SET UserUpdateONLY = NULL, UserUpdated = NEW.UserUpdateONLY
© www.soinside.com 2019 - 2024. All rights reserved.