繁体   English   中英

SQLite更新触发器更改表中的所有行

[英]SQLite update trigger changes all rows in the table

问题:最简单的更新触发器会将新值写入所有表行,而不仅仅是正在更新的行。 这是表格:

[名]

id INTEGER PRIMARY KEY
name TEXT
len INTEGER

现在我想创建触发器以'name'的长度更新'len'。 这个INSERT触发器似乎正在做核心工作:

CREATE TRIGGER 'namelen' AFTER INSERT ON 'names'
BEGIN
UPDATE 'names' SET len = length(NEW.name) WHERE (id=NEW.id);
END;

添加类似的UPDATE触发器时出现问题:

CREATE TRIGGER 'namelenupd' AFTER UPDATE ON 'names'
BEGIN
UPDATE 'names' SET len = length(NEW.name) WHERE (OLD.id=NEW.id);
END;

尽管有WHERE子句,update触发器会将新长度写入表的所有行 例如,如果我说

UPDATE 'names' SET name='foo' where id=1;

然后'len'的值对于表的所有行变为3。 我看过sqlite触发器示例,我看不到我的错误。 还有什么办法可以确保触发器在实际更新的行中更新'len'列?

OLD.xxx和NEW.xxx都引用导致触发器运行的表行。 触发器内的UPDATE语句独立运行; 如果要将其限制为一个表行,则必须通过对该语句的表值(即names.idid进行过滤,在其WHERE子句中显式执行此操作。

当原始UPDATE语句不更改id列时,旧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;

有同样的问题,这是我的触发器的语法

您可以将“ALTER”更改为“CREATE”,具体取决于您已经拥有(或不拥有)

您有"id"作为主键

你的dbo是"names"

显然,这会将名称值设置为“foo”(不是你想要的)。 键似乎是最后一行,您在其中设置inner join inserted on names.Id = inserted.Id

USE [yourDBname]
    ALTER TRIGGER [dbo].[yourTrigger]
       ON  [dbo].[names] 
       After INSERT, UPDATE 
    AS 

    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;

    Select id from inserted
        begin
         update [dbo].names
            set [dbo].names.name = 'foo' 
            from dbo.names 
               inner join inserted 
               on names.id = inserted.id
        END

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM