1.概述
delete-stmt:
common-table-expression:
select-stmt:
复合运算符:
加盟条款:
连接约束:
加入运营商:
订购期限:
结果栏:
表或子查询:
expr:
过滤器子句:
文字值:
子句:
框架规格:
订购期限:
提升功能:
select-stmt:
复合运算符:
加盟条款:
连接约束:
加入运营商:
订购期限:
结果栏:
表或子查询:
类型名称:
签名编号:
限定表名称:
返回条款:
DELETE命令从由qualified-table-name标识的表中删除记录
。
如果WHERE子句不存在,则删除表中的所有记录。如果提供了WHERE子句,则仅删除WHERE子句布尔表达式为true的那些行。保留表达式为false或NULL的行。
2.在CREATE TRIGGER中对DELETE语句的限制
以下限制适用于在CREATE TRIGGER语句内出现的DELETE语句:
在触发器主体中作为DELETE语句的一部分指定的表名必须是不合格的。换句话说就是
schema-name 。触发器中不允许在表名上添加前缀。如果触发器附加到的表不在临时数据库中,则触发器主体中的DELETE语句必须在与其相同的数据库中的表上进行操作。如果触发器附加到的表位于TEMP数据库中,则要删除的表的不合格名称的解析方式与顶级语句的解析方式相同(首先搜索TEMP数据库,然后搜索主数据库)数据库,然后按附加顺序排列其他任何数据库)。
触发器内的DELETE语句不允许使用INDEXED BY和NOT INDEXED子句。
触发器内的DELETE语句不支持LIMIT和ORDER BY子句(如下所述)。
触发器不支持RETURNING子句。
3.可选的LIMIT和ORDER BY子句
如果使用SQLITE_ENABLE_UPDATE_DELETE_LIMIT
编译时选项编译SQLite ,则通过添加可选的ORDER BY和LIMIT子句来扩展DELETE语句的语法:
delete-stmt-limited:
如果DELETE语句具有LIMIT子句,则可以通过评估附带的表达式并将其强制转换为整数值来找到要删除的最大行数。如果LIMIT子句的求值结果不能无损地转换为整数值,则是错误的。负LIMIT值将解释为“无限制”。如果DELETE语句还具有OFFSET子句,则将类似地对其进行评估并将其转换为整数值。同样,如果无法将值无损地转换为整数,则是错误的。如果没有OFFSET子句,或者计算的整数值为负,则有效的OFFSET值为零。
如果DELETE语句具有ORDER BY子句,则将根据ORDER BY对在缺少LIMIT子句的情况下将要删除的所有行进行排序。跳过前M行,其中M是通过评估OFFSET子句表达式找到的值,而后
N(其中N是LIMIT表达式的值)被删除。如果在考虑了OFFSET子句之后剩余少于N行,或者如果LIMIT子句评估为负值,则将删除所有剩余的行。
如果DELETE语句没有ORDER BY子句,则在应用LIMIT和OFFSET子句以确定实际删除的子集之前,将在不存在LIMIT子句的情况下删除的所有行以任意顺序组合。
DELETE语句上的ORDER BY子句仅用于确定哪些行在LIMIT之内。行的删除顺序是任意的,不受ORDER BY子句的影响。这意味着,如果存在RETURNING子句,则该语句返回的行可能不会按照ORDER BY子句指定的顺序。
4.截断优化
当从DELETE语句中省略WHERE子句和RETURNING子句,并且要删除的表没有触发器时,SQLite将使用优化来擦除整个表内容,而不必分别访问表的每一行。这种“截断”优化使删除运行更快。在SQLite 3.6.5(2008-11-12)版本之前,截断优化还意味着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操作将继续进行,但截断优化将被绕过,行将被一一删除。