SQLite 3.33添加了对从更新的支持

2020-08-16 19:31:26

UPDATE语句用于修改数据库表的零行或多行中存储的值的子集,该数据库表由指定为UPDATE语句一部分的限定表名标识。

如果UPDATE语句没有WHERE子句,则UPDATE将修改表中的所有行。否则,更新仅影响WHERE子句布尔表达式为TRUE的行。如果WHERE子句没有对表中的任何行求值为TRUE,这并不是错误的-这仅仅意味着UPDATE语句影响零行。

对受UPDATE语句影响的每一行所做的修改由SET关键字后面的赋值列表确定。每个赋值在等号左边指定一个列名,在右边指定一个标量表达式。对于每个受影响的行,命名列被设置为通过计算相应标量表达式找到的值。如果单个列名在赋值表达式列表中出现多次,则除了最右侧之外的所有匹配项都将被忽略。未出现在分配列表中的列保持不变。ScalareXpressions可以指正被更新的行的列。在这种情况下,在进行任何赋值之前都会计算所有标量表达式。

从SQLite版本3.15.0(2016-10-14)开始,SET子句中的赋值可以是左侧带括号的列名列表和右侧相同大小的行值。

UPDATE关键字后面的可选";OR操作&34;冲突子句允许用户指定在此更新命令期间使用的特定约束冲突解决算法。有关更多信息,请参阅标题为冲突的部分。

以下附加语法限制适用于出现在CREATE TRIGGER语句体内的UPDATE语句。

指定为触发器正文中UPDATE语句一部分的表名必须是非限定的。换句话说,就是schema-name。触发器内不允许在更新的表名称上添加前缀。除非触发器附加到的表在TEMP数据库中,否则由触发器程序更新的表必须位于与其相同的数据库中。如果触发器附加到的表在TEMP数据库中,则要更新的表的非限定名的解析方式与顶级语句的解析方式相同(首先搜索TEMP数据库,然后搜索主数据库,然后按附加顺序搜索任何其他数据库)。

触发器内的UPDATE语句不允许使用INDEX BY和NOT INDEX子句。

无论用于生成SQLite的编译选项如何,触发器中都不支持用于UPDATE的LIMIT和ORDER BY子句。

UPDATE-FROM IDEA是对SQL的扩展,它允许数据库中的其他表驱动UPDATE语句。目标表是正在更新的特定表。使用UPDATE-FROM,您可以针对数据库中的其他表联接目标表,以帮助计算哪些行需要更新以及这些行上应该有哪些新值。从SQLite版本3.33.0(2020-08-14)开始支持UPDATE-FROM。

其他关系数据库引擎也实现了UPDATE-FROM,但是因为该结构不是SQL标准的一部分,所以每个产品的UPDATE-FROM都是不同的。SQLite实现与PostgreSQL兼容。相同想法的SQL Server和MySQL实现的工作方式略有不同。

作为UPDATE-FROM如何有用的示例,假设您有一个在Sales表中累计购买的销售点应用程序。在一天结束的时候,你要根据每天的销售情况来调整库存表。为此,您可以对Inventory表运行更新,该表根据当天的合计销售额调整数量。该语句将如下所示:

更新存货集数量=Quantity-daily.amt自(选择SUM(数量)为金额,ITEMID从销售组按2)为日,其中ventory.itemId=daily.itemId;

FROM子句中的子查询计算每个ItemID的库存应该减少的金额。该子查询与Inventory表连接,并且每个受影响的库存行的数量减少适当的数量。

目标表不包括在FROM子句中,除非打算对目标表执行自联接。在自联接的情况下,FROM子句中的表必须使用与目标表不同的名称。

如果目标表和FROM子句之间的连接导致同一目标表行有多个输出行,那么这些输出行中只有一个用于更新目标表。选择的输出是任意的,可能会从一个SQLite版本到下一个版本,或者从一个运行到下一个运行。

SQL Server还支持UPDATE FROM,但在SQL Server中,目标表必须包含在FROM子句中。换句话说,目标表在语句中被命名了两次。使用SQL Server时,上面演示的库存调整语句将写成这样:

从存货更新存货集数量=Quantity-daily.amt,(选择金额为SUM(数量),从销售组选择ITEMID按2)为每日,其中ventory.itemId=daily.itemId;

MySQL支持UPDATE FROM IDEA,但是它没有使用FROM子句。相反,完整的连接规范在UPDATE和SET关键字之间给出。等效的MySQL语句如下所示:

更新库存连接(金额选择SUM(数量),销售组选择ITEMID为2)为日使用(ITEMID)set invventory.Quantity=invventory.Quantity-daily.amt;

与其他系统不同,MySQL UPDATE语句不只有一个目标表。可以在SET子句中修改参与联接的任何表。MySQL UPDATE语法允许您一次更新多个表!

如果SQLite是使用SQLITE_ENABLE_UPDATE_DELETE_LIMIT编译时间选项生成的,则UPDATE语句的语法将使用可选的ORDER BY和LIMIT子句进行扩展,如下所示:

如果UPDATE语句有LIMIT子句,则通过计算附带的表达式并将其转换为整数值,即可找到要更新的最大行数。负值被解释为";无限制";。

如果LIMIT表达式的计算结果为非负值N,并且UPDATE语句具有ORDER BY子句,则将根据ORDER BY对在没有LIMIT子句的情况下更新的所有行进行排序,并更新第一个N。如果UPDATE语句也有OFFSET子句,则类似地计算它并将其强制转换为整数值。如果OFFSETexpression的计算结果为非负值M,则跳过前几行,而更新后面的N行。

如果UPDATE语句没有ORDER BY子句,则在应用LIMIT和OFFSET子句之前,将按照任意顺序组装在没有LIMIT子句的情况下要更新的所有行,以确定实际更新了哪些行。

UPDATE语句上的ORDER BY子句仅用于确定哪些行在限制范围内。修改行的顺序是任意的,不受ORDER BY子句的影响。