我尝试向Sqlite3中的表添加UPDATE触发器,并且触发器会更新所有行,尽管我努力将其限制为仅实际更改的行。简单的化妆示例表:
CREATE TABLE IF NOT EXISTS prices (
id INTEGER PRIMARY KEY AUTOINCREMENT,
base REAL DEFAULT 100.0,
discount REAL DEFAULT 0.0,
actual REAL DEFAULT 0.0
);
INSERT INTO prices(base,discount,actual) VALUES (100,0,100),(200,0,200),(300,0,300);
应使用以下触发器更新实际价格:
CREATE TRIGGER "upd" AFTER UPDATE OF discount ON prices FOR EACH ROW
WHEN (OLD.discount <> NEW.discount)
BEGIN
UPDATE prices SET actual = base * (1-NEW.discount/100.0)
WHERE OLD.discount <> NEW.discount;
END;
如果我改变那么就说第二行:
UPDATE prices SET discount = 50 WHERE rowid = 2;
然后触发器在所有行上触发,不仅在第二行触发,并且所有行中的“实际”字段将乘以0.5。
正如您所看到的,触发器带有一个腰带和一个吊带:WHEN子句和WHERE子句都试图确保只有那些折扣值发生变化的行受到影响。通过指定/或WHEN,WHERE等来尝试所有4种组合无济于事。以下是UPDATE
:
1|100.0|0.0|50.0
2|200.0|50.0|100.0
3|300.0|0.0|150.0
请注意,有一个看似相关的SO question,但OP使用了以下子句:WHERE (OLD.id=NEW.id)
对于所有未更改的行当然是TRUE
,所以难怪它不起作用正如所料。我担心那里提供的解决方案不适用于我的情况。任何帮助将不胜感激。
编辑:CL之后。这里的-s解释是正确的触发器:
CREATE TRIGGER "upd" AFTER UPDATE OF discount ON prices FOR EACH ROW
BEGIN
UPDATE prices SET actual = base * (1-NEW.discount/100.0)
WHERE id = NEW.id; -- this selects the row that fired the trigger!
END;