nav*_*eet 13 sql sqlite join sql-update
这很容易,已被多次询问,但我无法让它工作.我认为应该工作的SQL查询是:
    UPDATE table2
       SET dst.a = dst.a + src.a,
           dst.b = dst.b + src.b,
           dst.c = dst.c + src.c,
           dst.d = dst.d + src.d,
           dst.e = dst.e + src.e
      FROM table2 AS dst 
INNER JOIN table1 AS src
        ON dst.f = src.f
Ton*_*bbs 25
使用update语句是不可能的,因为不支持更新语句中的sqlite连接.请参阅docs: update语句
如果您只想将单个列更新为静态值,则可以在update语句中正确使用子查询.请参阅此示例:如何在SQLite上连接表时进行更新?
现在在您的示例中,假设"列f"上有唯一键 - 我提出的解决方法/解决方案是使用replace语句:
replace into table2
(a, b, c, d, e, f, g)
select src.a, src.b, src.c, src.d, src.e, dest.f, dest.g
from table1 src
inner join table2 dest on src.f = dest.f
我还在table2"column g"中添加了一个额外的列,以显示如何使用此方法"更新"某些列.
另一件要谨慎的事情是,如果你使用"PRAGMA foreign_keys = ON;" 因为行被有效删除和插入,所以可能会出现问题.
我想出了一种使用TRIGGER的替代技术并"反转"更新的方向,尽管以源表中的虚拟字段为代价.
一般而言,您有一张Master桌子和一张Updates桌子.您希望Master从Updates关键字段链接的相应字段更新记录的部分/全部字段Key.
而不是UPDATE Master SET ... FROM Master INNER JOIN Updates ON Mater.Key = Updates.Key你做以下事情:
TriggerField向Updates表中添加虚拟字段以充当触发器的焦点.
在此字段上创建触发器:
CREATE TRIGGER UpdateTrigger AFTER UPDATE OF TriggerField ON Updates
BEGIN
    UPDATE Master SET
        Field1 = OLD.Field1,
        Field2 = OLD.Field2,
        ...
    WHERE Master.Key = OLD.Key
END;
使用以下命令启动更新过程:
UPDATE Updates SET TriggerField = NULL ;
虚拟字段仅仅是触发器的锚点,因此任何其他字段UPDATE Updates SET ...都不会触发更新Master.如果你只是INSERT进入Updates那时你不需要它(并且可以OF TriggerField在创建触发器时删除该子句).
从一些粗略和准备好的时间,这似乎与大致相同的速度,REPLACE INTO但避免了删除和添加行的感觉 - 稍微错误的技术.如果您只更新几个字段,那么它也更简单,Master因为您只列出要更改的字段.
它比我见过的其他替代方案快了几个数量级UPDATE ... FROM:
UPDATE Master SET
    Field1 = ( SELECT Field1 FROM Updates WHERE Mater.Key = Updates.Key ),
    Field1 = ( SELECT Field1 FROM Updates WHERE Mater.Key = Updates.Key ),
    ...
;
对于Tony和我的方法,在1700条记录中更新六个字段大约是0.05s,但是对于该方法来说是2.50sUPDATE ... ( SELECT... ).
AFTER UPDATE触发器Master似乎按预期触发.
| 归档时间: | 
 | 
| 查看次数: | 23153 次 | 
| 最近记录: |