DELETE
SQL As Understood By SQLite
[Top]
DELETE
delete-stmt:
hide
expr:
show
literal-value:
show
raise-function:
show
select-stmt:
show
common-table-expression:
show
compound-operator:
show
join-clause:
show
join-constraint:
show
join-operator:
show
ordering-term:
show
result-column:
show
table-or-subquery:
show
type-name:
show
signed-number:
show
qualified-table-name:
show
with-clause:
show
cte-table-name:
show
select-stmt:
show
common-table-expression:
show
compound-operator:
show
join-clause:
show
join-constraint:
show
join-operator:
show
ordering-term:
show
result-column:
show
table-or-subquery:
show
DELETE 命令从由 qualified-table-name 标识的表中删除记录。
如果 WHERE 子句不存在,则删除表中的所有记录。如果提供了 WHERE 子句,那么只有那些 WHERE 子句布尔表达式为真的行才会被删除。表达式为 false 或 NULL 的行将被保留。
对 CREATE TRIGGER 中的 DELETE 语句的限制
以下限制适用于在 CREATE TRIGGER 语句的主体内发生的 DELETE 语句:
- 在触发器体内指定为 DELETE 语句一部分的表名必须是不合格的
。
换句话说,模式名称。
表名中的前缀在触发器中是不允许的。
如果触发器附加到的表不在临时数据库中,则触发器正文内的 DELETE 语句必须在与其相同的数据库中的表上操作。
如果触发器附加到的表在 TEMP 数据库中,那么将删除正被删除的表的非限定名称,方式与顶级语句相同(通过首先搜索 TEMP 数据库,然后选择 main 数据库,然后是任何其他数据库按照它们附加的顺序)。
- 触发器中的 DELETE 语句不允许 INDEXED BY 和 NOT INDEXED 子句。
- 触发器中的 DELETE 语句不支持 LIMIT 和 ORDER BY 子句(如下所述)。
可选的 LIMIT 和 ORDER BY 子句
如果 SQLite 使用 SQLITE_ENABLE_UPDATE_DELETE_LIMIT 编译时选项进行编译,则通过添加可选的 ORDER BY 和 LIMIT 子句来扩展 DELETE 语句的语法:
delete-stmt-limited:
如果 DELETE 语句具有 LIMIT 子句,则通过评估随附的表达式并将其转换为整数值来找到将被删除的最大行数。如果评估 LIMIT 子句的结果不能无损地转换为整数值,那就是错误。负的 LIMIT 值被解释为“无限制”。如果 DELETE 语句也有一个 OFFSET 子句,那么它将被类似地评估并转换为一个整数值。同样,如果该值无法无损地转换为整数,则会出错。如果没有 OFFSET 子句,或者计算的整数值为负数,则有效的 OFFSET 值为零。
如果 DELETE 语句具有 ORDER BY 子句,则在缺少 LIMIT 子句的情况下将删除的所有行都将根据 ORDER BY 进行排序。第一中号行,其中中号是通过评估 OFFSET 子句表达式中找到的值,会被跳过,以下 Ñ,其中 Ñ 是 LIMIT 表达式的值,将被删除。如果在考虑 OFFSET 子句后剩余的行数少于 N 行,或者 LIMIT 子句评估为负值,则删除所有剩余的行。
如果 DELETE 语句没有 ORDER BY 子句,那么在应用 LIMIT 和 OFFSET 子句以确定实际删除的子集之前,在没有 LIMIT 子句的情况下将被删除的所有行将按任意顺序汇编。
DELETE 语句上的 ORDER BY 子句仅用于确定哪些行位于 LIMIT 内。删除行的顺序是任意的,不受 ORDER BY 子句的影响。
截断优化
当从 DELETE 语句中省略 WHERE 并且被删除的表没有触发器时,SQLite 使用优化来擦除整个表内容,而不必逐个访问表中的每一行。这种“截断”优化使删除运行速度更快。在 SQLite 版本3.6.5(2008-11-12)之前,truncate 优化还意味着 sqlite3_changes()和 sqlite3_total_changes()接口和 count_changes编译指示实际上不会返回已删除行的数量。该问题已在版本3.6.5(2008-11-12)中得到修复。
通过使用 SQLITE_OMIT_TRUNCATE_OPTIMIZATION 编译时开关重新编译 SQLite,可以永久禁用所有查询的截断优化。
截断优化也可以在运行时使用 sqlite3_set_authorizer()接口禁用。如果授权方回调为 SQLITE_DELETE 操作代码返回 SQLITE_IGNORE,则 DELETE 操作将继续,但截断优化将被绕过,行将逐个删除。