问题:最简单的更新触发器会将新值写入所有表行,而不仅仅是正在更新的行.这是表格:
[名]
id INTEGER PRIMARY KEY
name TEXT
len INTEGER
Run Code Online (Sandbox Code Playgroud)
现在我想创建触发器以'name'的长度更新'len'.这个INSERT触发器似乎正在做核心工作:
CREATE TRIGGER 'namelen' AFTER INSERT ON 'names'
BEGIN
UPDATE 'names' SET len = length(NEW.name) WHERE (id=NEW.id);
END;
Run Code Online (Sandbox Code Playgroud)
添加类似的UPDATE触发器时出现问题:
CREATE TRIGGER 'namelenupd' AFTER UPDATE ON 'names'
BEGIN
UPDATE 'names' SET len = length(NEW.name) WHERE (OLD.id=NEW.id);
END;
Run Code Online (Sandbox Code Playgroud)
尽管有WHERE子句,update触发器会将新长度写入表的所有行.例如,如果我说
UPDATE 'names' SET name='foo' where id=1;
Run Code Online (Sandbox Code Playgroud)
然后'len'的值对于表的所有行变为3 .我看过sqlite触发器示例,我看不到我的错误.还有什么办法可以确保触发器仅在实际更新的行中更新'len'列?
CL.*_*CL. 10
OLD.xxx和NEW.xxx都引用导致触发器运行的表行.触发器内的UPDATE语句独立运行; 如果要将其限制为一个表行,则必须通过对该语句的表值进行过滤来明确地在其WHERE子句中执行此操作,即,names.id或者只是id.
当原始UPDATE语句不更改id列时,旧id值和新值相同,表达式OLD.id=NEW.id对于表中的所有记录都为true ,如内部UPDATE语句所示.
正确的触发器如下所示:
CREATE TRIGGER "namelenupd"
AFTER UPDATE OF name ON "names"
BEGIN
UPDATE "names" SET len = length(NEW.name) WHERE id = NEW.id;
END;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3653 次 |
| 最近记录: |