我一直遵循此处的指南:https://www.northrivergeographic.com/adding-triggers-to-geopackage/将触发器添加到 Geopackage 文件中的 SQLite 数据库。几何类型是线(LineStringZM)。
我想要它做的是在创建新记录时使用QGIS数字化工具栏中的
Toggle Editing > Add Line Feature
自动计算线长度并更新名为“长度”的字段。很简单...除了触发器似乎会更新所有记录并添加最新行的长度。
我的代码如下:
CREATE TRIGGER update_Length_after_Insert AFTER INSERT
ON WaterwayOptions
BEGIN
UPDATE WaterwayOptions SET Length = (SELECT ST_Length(new.geom) FROM WaterwayOptions );
END
我考虑添加一个
WHEN old.geom <> new.geom
过滤器(如此处的示例:https://www.sqlitetutorial.net/sqlite-trigger/)子句,但这在创建新记录时会失败。
我的逻辑有什么错误?
我的逻辑有什么错误?
插入时不旧。?只有新的。?用柱无旧。预选赛。也可能在 WHERE 子句中而不是在 WHEN 中,例如
UPDATE WaterwayOptions SET Length = (SELECT ST_Length(new.geom) FROM WaterwayOptions ) WHERE geom = new.geom;
如果您尝试使用 WHEN 子句来尝试查看新的
geom
之前是否不存在,那么您将会遇到问题,因为在插入之后,就事务而言,它确实存在(BEFORE 被警告)。
如果使用更复杂的 WHEN 子句(请参阅演示)发现已插入新的 geom 行(请参阅演示),则 UPDATE 仍会更新所有行。
因此,需要 UPDATE 上的 WHERE 子句,因此 UPDATE 上的 WHERE 子句很可能是最佳解决方案。
也许可以考虑下面的演示,它近似于您正在做的事情。
它经历 4 个触发器
除了创建触发器之外,代码是相同的(插入相同的数据)
演示代码/SQL:-
/* ATTEMPT 1 (original)*/
DROP TABLE IF EXISTS WaterwayOptions;
CREATE TABLE IF NOT EXISTS WaterwayOptions (woId TEXT PRIMARY KEY, geom TEXT UNIQUE, `length` INTEGER, othercol TEXT DEFAULT 'blah');
CREATE TRIGGER update_Length_after_Insert AFTER INSERT
ON WaterwayOptions
BEGIN
UPDATE WaterwayOptions SET Length = (SELECT Length(new.geom) FROM WaterwayOptions );
END
;
INSERT INTO WaterwayOptions (woid,geom,`length`)
VALUES
('wo1','geoma',10),
('wo2','geomaa',10),
('wo3','geomaaa',10)
;
SELECT * FROM waterwayoptions;
/* ATTEMPT 2 (WHERE clause for the UPDATE)*/
DROP TABLE IF EXISTS WaterwayOptions;
CREATE TABLE IF NOT EXISTS WaterwayOptions (woId TEXT PRIMARY KEY, geom TEXT UNIQUE, `length` INTEGER, othercol TEXT DEFAULT 'blah');
DROP TRIGGER IF EXISTS update_Length_after_Insert;
CREATE TRIGGER update_Length_after_Insert AFTER INSERT
ON WaterwayOptions
BEGIN
UPDATE WaterwayOptions SET Length = (SELECT Length(new.geom) FROM WaterwayOptions ) WHERE geom=new.geom;
END
;
INSERT INTO WaterwayOptions (woid,geom,`length`)
VALUES
('wo1','geoma',10),
('wo2','geomaa',10),
('wo3','geomaaa',10)
;
SELECT * FROM waterwayoptions;
/* ATTEMPT 3 (simple WHEN) */
DROP TABLE IF EXISTS WaterwayOptions;
CREATE TABLE IF NOT EXISTS WaterwayOptions (woId TEXT PRIMARY KEY, geom TEXT UNIQUE, `length` INTEGER, othercol TEXT DEFAULT 'blah');
DROP TRIGGER IF EXISTS update_Length_after_Insert;
CREATE TRIGGER update_Length_after_Insert AFTER INSERT
ON WaterwayOptions WHEN new.geom NOT IN (SELECT geom FROM WaterwayOptions)
BEGIN
UPDATE WaterwayOptions SET Length = (SELECT Length(new.geom) FROM WaterwayOptions );
END
;
INSERT INTO WaterwayOptions (woid,geom,`length`)
VALUES
('wo1','geoma',10),
('wo2','geomaa',10),
('wo3','geomaaa',10)
;
SELECT * FROM waterwayoptions;
/* ATTEMPT 4 (more complex WHEN) */
DROP TABLE IF EXISTS WaterwayOptions;
CREATE TABLE IF NOT EXISTS WaterwayOptions (woId TEXT PRIMARY KEY, geom TEXT UNIQUE, `length` INTEGER, othercol TEXT DEFAULT 'blah');
DROP TRIGGER IF EXISTS update_Length_after_Insert;
CREATE TRIGGER update_Length_after_Insert AFTER INSERT
ON WaterwayOptions WHEN new.geom NOT IN (SELECT geom FROM WaterwayOptions WHERE geom <> new.geom)
BEGIN
UPDATE WaterwayOptions SET Length = (SELECT Length(new.geom) FROM WaterwayOptions);
END
;
INSERT INTO WaterwayOptions (woid,geom,`length`)
VALUES
('wo1','geoma',10),
('wo2','geomaa',10),
('wo3','geomaaa',10)
;
SELECT * FROM waterwayoptions;
结果(在插入之后选择,因此触发):-
UPDATE .... WHERE ....
每行已更新为将 10 更改为 geom 列的长度(正确)