支持的 SQL 语法

本部分介绍 Adobe AIR SQL 数据库引擎支持的 SQL 语法。 下面所列的各项分别用于说明不同的语句和子句类型、表达式、内置函数和运算符。本部分包含以下主题:
  • 常规 SQL 语法

  • 数据操作语句(SELECT、INSERT、UPDATE 和 DELETE)

  • 数据定义语句(用于表、索引、视图和触发器的 CREATE、ALTER 和 DROP 语句)

  • 特殊的语句和子句

  • 内置函数(聚合函数、标量函数和日期/时间格式函数)

  • 运算符

  • 参数

  • 不支持的 SQL 功能

  • 其他 SQL 功能

常规 SQL 语法

除了各种语句和表达式的特定语法外,以下是 SQL 语法的一般规则:
区分大小写
SQL 语句(包括对象名称)不区分大小写。但是,SQL 语句经常以大写形式的 SQL 关键字编写,本文档使用了该约定。尽管 SQL 语法不区分大小写,但是 SQL 中的文本值区分大小写,而且比较和排序操作可区分大小写,如为列或操作定义的排序规则序列所指定的。有关详细信息,请参阅 COLLATE。

空白
必须使用空白字符(如空格、制表符、换行符等)来分隔 SQL 语句中的各个单词。但是,单词和符号之间的空白是可选的。SQL 语句中空白字符的类型和数量并不重要。可使用空白(如缩进和换行符)来设置 SQL 语句的格式以便于阅读,而不影响语句的含义。

数据操作语句

数据操作语句是最常用的 SQL 语句。这些语句用于从数据库表检索、添加、修改和删除数据。支持以下数据操作语句:SELECT、INSERT、UPDATE 和 DELETE。

SELECT

SELECT 语句用于查询数据库。SELECT 的结果是零行或多行数据,其中每行都具有固定的列数。结果中的列数由 result 列名称或 SELECT 和可选 FROM 关键字之间的表达式列表指定。

sql-statement   ::=  SELECT [ALL | DISTINCT] result 
                     [FROM table-list] 
                     [WHERE expr] 
                     [GROUP BY expr-list] 
                     [HAVING expr] 
                     [compound-op select-statement]* 
                     [ORDER BY sort-expr-list] 
                     [LIMIT integer [( OFFSET | , ) integer]] 
result          ::=  result-column [, result-column]* 
result-column   ::=  * | table-name . * | expr [[AS] string] 
table-list      ::=  table [ join-op table join-args ]* 
table           ::=  table-name [AS alias] | 
                     ( select ) [AS alias] 
join-op         ::=  , | [NATURAL] [LEFT | RIGHT | FULL] [OUTER | INNER | CROSS] JOIN 
join-args       ::=  [ON expr] [USING ( id-list )] 
compound-op     ::=  UNION | UNION ALL | INTERSECT | EXCEPT 
sort-expr-list  ::=  expr [sort-order] [, expr [sort-order]]* 
sort-order      ::=  [COLLATE collation-name] [ASC | DESC] 
collation-name  ::=  BINARY | NOCASE

任意的表达式都可用作结果。如果结果表达式是 *,则以所有表的所有列替换该表达式。如果表达式是表名后跟 .*,则结果是该表中的所有列。

DISTINCT 关键字可导致返回结果行的子集,其中每个结果行都不同。各 NULL 值不被视为彼此不同。默认行为是返回所有结果行,这可通过关键字 ALL 明确指定。

对在 FROM 关键字后指定的一个或多个表执行查询。如果多个表名由逗号分隔,则查询将使用各个表的交叉联接。JOIN 语法还可用于指定如何联接表。支持的唯一一个外部联接类型是 LEFT OUTER JOIN。join-args 中的 ON 子句表达式必须解析为布尔值。括号中的子查询可用作 FROM 子句中的表。可省略整个 FROM 子句,在此情况下结果是由 result 表达式列表的值组成的单个行。

WHERE 子句用于限制查询所检索的行数。WHERE 子句表达式必须解析为布尔值。WHERE 子句筛选是在任何分组之前执行的,因此 WHERE 子句表达式不能包括聚合函数。

GROUP BY 子句导致将结果的一行或多行合并到输出的单个行中。当结果包含聚合函数时,GROUP BY 子句尤其有用。GROUP BY 子句中的表达式不必是出现在 SELECT 表达式列表中的表达式。

HAVING 子句与 WHERE 类似,因为它限制语句返回的行数。但是,HAVING 子句在发生由 GROUP BY 子句指定的任何分组后应用。因此,HAVING 表达式可能引用包括聚合函数的值。不要求 HAVING 子句表达式出现在 SELECT 列表中。与 WHERE 表达式一样,HAVING 表达式必须解析为布尔值。

ORDER BY 子句导致对输出行进行排序。ORDER BY 子句的 sort-expr-list 参数是用作排序关键字的表达式列表。对于简单的 SELECT,这些表达式不必是结果的一部分,但是在复合 SELECT(使用 compound-op 运算符之一的 SELECT)中,每个排序表达式都必须与结果列之一完全匹配。每个排序表达式可能(可选)后跟 sort-order 子句,该子句包含 COLLATE 关键字以及用于对文本进行排序的排序规则函数的名称和/或用于指定排序顺序(升序或降序)的关键字 ASC 或 DESC。可省略排序顺序,在此情况下将使用默认值(升序)。有关 COLLATE 子句和排序规则函数的定义,请参阅 COLLATE。

LIMIT 子句为结果中返回的行数设定上限。负的 LIMIT 指示无上限。LIMIT 后面的可选 OFFSET 指定要在结果集开头跳过的行数。在复合 SELECT 查询中,LIMIT 子句可能仅出现在最终 SELECT 语句之后,并且限制应用于整个查询。请注意,如果在 LIMIT 子句中使用 OFFSET 关键字,则限制是第一个整数,偏移量是第二个整数。如果使用逗号而不是 OFFSET 关键字,则偏移量是第一个数,限制是第二个数。此表面上的矛盾是有意的 — 这最大限度提高了与早期 SQL 数据库系统的兼容性。

复合 SELECT 是由运算符 UNION、UNION ALL、INTERSECT 或 EXCEPT 之一所连接的两个或更多个简单 SELECT 语句构成的。在复合 SELECT 中,所有用于构成的 SELECT 语句都必须指定相同数量的结果列。在最终 SELECT 语句之后只能有一个 ORDER BY 子句(如果指定了单个 LIMIT 子句,还要在这类子句之前)。UNION 和 UNION ALL 运算符将前面和后面的 SELECT 语句的结果组合到单个表中。两者的差异在于,在 UNION 中,所有结果行都不重复,但是在 UNION ALL 中,则可能存在重复行。INTERSECT 运算符求出前面和后面的 SELECT 语句的结果的交集。在删除后面的 SELECT 的结果后,EXCEPT 求出前面的 SELECT 的结果。将三个或更多 SELECT 语句连接为复合语句时,它们从第一个到最后一个进行组合。

有关允许的表达式的定义,请参阅表达式。

从 AIR 2.5 开始,为了将 BLOB 数据转换为 ActionScript ByteArray 对象而进行读取时,支持 SQL CAST 运算符。例如,以下代码读取不以 AMF 格式存储的原始数据并将该数据存储在 ByteArray 对象中:

stmt.text = "SELECT CAST(data AS ByteArray) AS data FROM pictures;"; 
stmt.execute(); 
var result:SQLResult = stmt.getResult(); 
var bytes:ByteArray = result.data[0].data;

INSERT

INSERT 语句有两种基本形式,它用于用数据填充表。
sql-statement  ::=  INSERT [OR conflict-algorithm] INTO [database-name.] table-name [(column-list)] VALUES (value-list) | 
                    INSERT [OR conflict-algorithm] INTO [database-name.] table-name [(column-list)] select-statement 
                    REPLACE INTO [database-name.] table-name [(column-list)] VALUES (value-list) | 
                    REPLACE INTO [database-name.] table-name [(column-list)] select-statement

第一种形式(使用 VALUES 关键字)在现有表中创建单个新行。如果未指定 column-list,则值的数量必须等于表中的列数。如果指定了 column-list,则值的数量必须与指定列的数量匹配。将用创建表时定义的默认值填充未出现在列的列表中的表列;如果未定义默认值,则使用 NULL 填充。

INSERT 语句的第二种形式从 SELECT 语句提取其数据。如果未指定 column-list,则 SELECT 的结果中的列数必须与表中的列数完全匹配,或者它必须与在 column-list 中指定的列数完全匹配。在表中为 SELECT 结果的每一行创建一个新项。SELECT 可能是简单的或复合的。有关允许的 SELECT 语句的定义,请参阅 SELECT。

可选的 conflict-algorithm 允许指定要在此命令过程中使用的替代约束冲突解决算法。有关冲突算法的解释和定义,请参阅 特殊的语句和子句

该语句的两种 REPLACE INTO 形式等效于将标准的 INSERT [OR conflict-algorithm] 形式与 REPLACE 冲突算法一起使用(即 INSERT OR REPLACE... 形式)。

该语句的两种 REPLACE INTO 形式等效于将标准的 INSERT [OR conflict-algorithm] 形式与 REPLACE 冲突算法一起使用(即 INSERT OR REPLACE... 形式)。

UPDATE

update 命令可更改表中的现有记录。

sql-statement  ::=  UPDATE [database-name.] table-name SET column1=value1, column2=value2,... [WHERE expr]

该命令由 UPDATE 关键字后跟要更新记录的表的名称组成。在 SET 关键字之后,采用逗号分隔的列表形式提供列名称以及要将该列更改为的值。WHERE 子句表达式提供要更改其记录的一个或多个行。

DELETE

delete 命令用于从表中删除记录。
sql-statement  ::=  DELETE FROM [database-name.] table-name [WHERE expr]

该命令由 DELETE FROM 关键字后跟要从其删除记录的表的名称组成。

如果没有 WHERE 子句,则删除表的所有行。如果提供了 WHERE 子句,则仅删除与表达式匹配的那些行。WHERE 子句表达式必须解析为布尔值。有关允许的表达式的定义,请参阅表达式。

数据定义语句

数据定义语句用于创建、修改和删除数据库对象,如表、视图、索引和触发器。支持以下数据定义语句:
  • 表:
    • CREATE TABLE

    • ALTER TABLE

    • DROP TABLE

  • 索引:
    • CREATE INDEX

    • DROP INDEX

  • 视图:
    • CREATE VIEWS

    • DROP VIEWS

  • 触发器:
    • CREATE TRIGGERS

    • DROP TRIGGERS

CREATE TABLE

CREATE TABLE 语句由关键字 CREATE TABLE 后跟新表的名称以及列定义和约束的列表(在括号中)组成。表名可以是标识符或字符串。
sql-statement       ::=  CREATE [TEMP | TEMPORARY] TABLE [IF NOT EXISTS] [database-name.] table-name 
                         ( column-def [, column-def]* [, constraint]* ) 
sql-statement       ::=  CREATE [TEMP | TEMPORARY] TABLE [database-name.] table-name AS select-statement 
column-def          ::=  name [type] [[CONSTRAINT name] column-constraint]* 
type                ::=  typename | typename ( number ) | typename ( number , number ) 
column-constraint   ::=  NOT NULL [ conflict-clause ] | 
                         PRIMARY KEY [sort-order] [ conflict-clause ] [AUTOINCREMENT] | 
                         UNIQUE [conflict-clause] | 
                         CHECK ( expr ) | 
                         DEFAULT default-value | 
                         COLLATE collation-name 
constraint          ::=  PRIMARY KEY ( column-list ) [conflict-clause] | 
                         UNIQUE ( column-list ) [conflict-clause] | 
                         CHECK ( expr ) 
conflict-clause     ::=  ON CONFLICT conflict-algorithm 
conflict-algorithm  ::=  ROLLBACK | ABORT | FAIL | IGNORE | REPLACE 
default-value       ::=  NULL | string | number | CURRENT_TIME | CURRENT_DATE | CURRENT_TIMESTAMP 
sort-order          ::=  ASC | DESC 
collation-name      ::=  BINARY | NOCASE 
column-list         ::=  column-name [, column-name]*

每个列定义都是列的名称后跟该列的数据类型,然后是一个或多个可选的列约束。列的数据类型限制可在该列中存储的数据。如果尝试在具有不同数据类型的列中存储某个值,则运行时会将该值转换为相应的类型(如果可能),或者引发错误。有关其他信息,请参阅数据类型支持部分。

NOT NULL 列约束指示列不能包含 NULL 值。

UNIQUE 约束导致在指定的一个或多个列上创建索引。此索引必须包含唯一键 — 没有任何两行可以包含重复值或者指定的一个或多个列的值的组合。CREATE TABLE 语句可具有多个 UNIQUE 约束(包括列定义中有 UNIQUE 约束的多个列)和/或多个表级 UNIQUE 约束。

CHECK 约束定义计算结果必须为 true 的表达式,以便插入或更新行的数据。CHECK 表达式必须解析为布尔值。

列定义中的 COLLATE 子句指定在比较列的文本项时要使用的文本排序规则函数。默认情况下,使用 BINARY 排序规则函数。有关 COLLATE 子句和排序规则函数的详细信息,请参阅 COLLATE。

DEFAULT 约束指定执行 INSERT 时要使用的默认值。该值可能是 NULL、字符串常量或数字。默认值还可能是与大小写无关的特殊关键字 CURRENT_TIME、CURRENT_DATE 或 CURRENT_TIMESTAMP 之一。如果该值是 NULL、字符串常量或数字,则只要 INSERT 语句不指定列的值,则按字面将它插入到列中。如果该值是 CURRENT_TIME、CURRENT_DATE 或 CURRENT_TIMESTAMP,则将当前的 UTC 日期和/或时间插入到列中。对于 CURRENT_TIME,格式为 HH:MM:SS。对于 CURRENT_DATE,格式为 YYYY-MM-DD。CURRENT_TIMESTAMP 的格式为 YYYY-MM-DD HH:MM:SS。

指定 PRIMARY KEY 通常仅在对应的一个或多个列上创建 UNIQUE 索引。但是,如果 PRIMARY KEY 约束在具有数据类型 INTEGER(或它的一个同义词,如 int)的单个列上,则数据库会将该列用作表的实际主键。这意味着该列只能保存唯一整数值。(注意:在许多 SQLite 实现中,只有列类型 INTEGER 会导致列用作内部主键,但在 Adobe AIR 中,INTEGER 的同义词,如 int,也会指定该行为。)

如果表没有 INTEGER PRIMARY KEY 列,则在插入行时将自动生成整数键。使用特殊名称 ROWID、OID 或 _ROWID_ 之一,始终可以访问行的主键。可使用这些名称,而不管它是明确声明的 INTEGER PRIMARY KEY 还是内部生成的值。但是,如果表具有显式 INTEGER PRIMARY KEY,则结果数据中的列名称是实际列名称,而不是特殊名称。

INTEGER PRIMARY KEY 列还可包括关键字 AUTOINCREMENT。如果使用 AUTOINCREMENT 关键字,则在执行未指定列的显式值的 INSERT 语句时,数据库会在 INTEGER PRIMARY KEY 列中自动生成并插入按顺序递增的整数键。

CREATE TABLE 语句中只能有一个 PRIMARY KEY 约束。它可以是一个列的定义的一部分或一个单表级 PRIMARY KEY 约束。主键列隐式为 NOT NULL。

许多约束后面的可选 conflict-clause 允许为该约束指定替代的默认约束冲突解决算法。默认值为 ABORT。同一表中的不同约束可能具有不同的默认冲突解决算法。如果 INSERT 或 UPDATE 语句指定不同的冲突解决算法,则使用该算法,替代在 CREATE TABLE 语句中指定的算法。请参阅 特殊的语句和子句 的 ON CONFLICT 部分,了解更多信息。

其他约束(如 FOREIGN KEY 约束)不会导致错误,但运行时会忽略它们。

如果在 CREATE 和 TABLE 之间出现 TEMP 或 TEMPORARY 关键字,则创建的表仅在同一数据库连接(SQLConnection 实例)内才是可见的。关闭数据库连接时会自动删除它。在临时表上创建的任何索引也是临时的。临时的表和索引存储在与主数据库文件不同的单独文件中。

如果指定可选的 database-name 前缀,则在指定的数据库(通过使用指定的数据库名称调用 attach() 方法连接到 SQLConnection 实例的数据库)中创建表。除非 database-name 前缀是 temp,否则同时指定 database-name 前缀和 TEMP 关键字是错误的。如果未指定数据库名称,而且不存在 TEMP 关键字,则在主数据库(使用 open() 或 openAsync() 方法连接到 SQLConnection 实例的数据库)中创建表。

对表中的列数或约束数没有任何限制。对行中的数据量也没有任何限制。

CREATE TABLE AS 形式将表定义为查询的结果集。表列的名称是结果中列的名称。

如果存在可选的 IF NOT EXISTS 子句,而且同名的其他表已存在,则数据库将忽略 CREATE TABLE 命令。

可使用 DROP TABLE 语句删除表,并可使用 ALTER TABLE 语句进行有限的更改。

ALTER TABLE

ALTER TABLE 命令允许用户重命名现有表或向其添加新列。无法从表中删除列。

sql-statement ::= ALTER TABLE [database-name.] table-name alteration 
alteration    ::= RENAME TO new-table-name 
alteration    ::= ADD [COLUMN] column-def

RENAME TO 语法用于将由 [database-name.] table-name 标识的表重命名为 new-table-name。此命令不能用于在附加的数据库之间移动表,而只能用于重命名同一数据库中的表。

如果要重命名的表具有触发器或索引,则在重命名表后,这些触发器或索引仍然附加到表。但是,如果存在任何视图定义或由引用要重命名的表的触发器执行的语句,则不会自动修改它们以使用新表名。如果重命名的表具有关联的视图或触发器,则必须手动删除再重新创建使用新表名的触发器或视图定义。

ADD [COLUMN] 语法用于向现有表添加新列。新列始终追加到现有列的列表的结尾。column-def 子句可采用 CREATE TABLE 语句中允许的任何形式,但有以下限制:

  • 列不能具有 PRIMARY KEY 或 UNIQUE 约束。

  • 列不能具有默认值 CURRENT_TIME、CURRENT_DATE 或 CURRENT_TIMESTAMP。

  • 如果指定了 NOT NULL 约束,则列必须具有除 NULL 之外的默认值。

ALTER TABLE 语句的执行时间不受表中数据量的影响。

DROP TABLE

DROP TABLE 语句删除使用 CREATE TABLE 语句添加的表。具有指定 table-name 的表就是所删除的表。它将从数据库和磁盘文件中完全删除。无法恢复表。与表关联的所有索引也将被删除。
sql-statement  ::=  DROP TABLE [IF EXISTS] [database-name.] table-name

默认情况下,DROP TABLE 语句不减小数据库文件的大小。将保留数据库中的空白空间,并在后续 INSERT 操作中使用。若要删除数据库中的可用空间,请使用 SQLConnection.clean() 方法。如果在最初创建数据库时 autoClean 参数设置为 true,则将自动释放空间。

可选的 IF EXISTS 子句抑制表不存在时通常会导致的错误。

CREATE INDEX

CREATE INDEX 命令包含关键字 CREATE INDEX,后跟新索引的名称、关键字 ON、之前创建的要编制索引的表的名称,以及表中其值用于索引键的列的名称的带括号列表。

sql-statement  ::=  CREATE [UNIQUE] INDEX [IF NOT EXISTS] [database-name.] index-name 
                    ON table-name ( column-name [, column-name]* ) 
column-name    ::=  name [COLLATE collation-name] [ASC | DESC]

每个列名都可后跟 ASC 或 DESC 关键字以指示排序顺序,但运行时会忽略指定的排序顺序。排序始终按升序执行。

每个列名后面的 COLLATE 子句定义用于该列中文本值的排序规则序列。默认的排序规则序列是在 CREATE TABLE 语句中为该列定义的排序规则序列。如果未指定排序规则序列,则使用 BINARY 排序规则序列。有关 COLLATE 子句和排序规则函数的定义,请参阅 COLLATE。

对于可附加到单个表的索引数没有任何限制。对于索引中的列数也没有限制。

DROP INDEX

drop index 语句删除使用 CREATE INDEX 语句添加的语句。指定的索引将从数据库文件中完全删除。恢复索引的唯一方法是,重新输入相应的 CREATE INDEX 命令。

sql-statement ::= DROP INDEX [IF EXISTS] [database-name.] index-name

默认情况下,DROP INDEX 语句不减小数据库文件的大小。将保留数据库中的空白空间,并在后续 INSERT 操作中使用。若要删除数据库中的可用空间,请使用 SQLConnection.clean() 方法。如果在最初创建数据库时 autoClean 参数设置为 true,则将自动释放空间。

CREATE VIEW

CREATE VIEW 命令为预定义的 SELECT 语句分配一个名称。之后,此新名称可用于其他 SELECT 语句的 FROM 子句中来代替表名。视图通常用于简化查询,方法是将一组复杂的(和频繁使用的)数据组合到可在其他操作中使用的结构中。

sql-statement ::= CREATE [TEMP | TEMPORARY] VIEW [IF NOT EXISTS] [database-name.] view-name AS select-statement

如果在 CREATE 和 VIEW 之间出现 TEMP 或 TEMPORARY 关键字,则创建的视图仅对已打开数据库的 SQLConnection 实例是可见的,并且在关闭数据库时会自动删除该视图。

如果指定了 [database-name],则使用指定的 name 参数在指定的数据库(使用 attach() 方法连接到 SQLConnection 实例的数据库)中创建视图。除非 [database-name] 是 temp,否则同时指定 [database-name] 和 TEMP 关键字是错误的。如果未指定数据库名称,而且不存在 TEMP 关键字,则在主数据库(使用 open() 或 openAsync() 方法连接到 SQLConnection 实例的数据库)中创建视图。

视图是只读的。除非至少定义一个关联类型(INSTEAD OF DELETE、INSTEAD OF INSERT、INSTEAD OF UPDATE)的触发器,否则不能对视图使用 DELETE、INSERT 或 UPDATE 语句。有关为视图创建触发器的信息,请参阅 CREATE TRIGGER。

使用 DROP VIEW 语句可从数据库中删除视图。

DROP VIEW

DROP VIEW 语句删除由 CREATE VIEW 语句创建的视图。

sql-statement ::= DROP VIEW [IF EXISTS] view-name

指定的 view-name 是要删除的视图的名称。将从数据库中删除它,但不会修改基础表中的数据。

CREATE TRIGGER

create trigger 语句用于向数据库架构添加触发器。触发器是在发生指定的数据库事件 (database-event) 时自动执行的数据库操作 (trigger-action)。

sql-statement   ::=  CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] [database-name.] trigger-name 
                     [BEFORE | AFTER] database-event 
                     ON table-name 
                     trigger-action 
sql-statement   ::=  CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] [database-name.] trigger-name 
                     INSTEAD OF database-event 
                     ON view-name 
                     trigger-action 
database-event  ::=  DELETE | 
                     INSERT | 
                     UPDATE | 
                     UPDATE OF column-list 
trigger-action  ::=  [FOR EACH ROW] [WHEN expr] 
                     BEGIN 
                       trigger-step ; 
                       [ trigger-step ; ]* 
                     END 
trigger-step    ::=  update-statement | 
                     insert-statement | 
                     delete-statement | 
                     select-statement 
column-list     ::=  column-name [, column-name]*

触发器被指定为只要出现以下条件就会激发:发生特定数据库表的 DELETE、INSERT 或 UPDATE,或者更新了表的一个或多个指定列的 UPDATE。除非使用了 TEMP 或 TEMPORARY 关键字,否则触发器是永久性的。在这种情况下,当关闭 SQLConnection 实例的主数据库连接时,将删除触发器。如果未指定时间(BEFORE 或 AFTER),则触发器默认为 BEFORE。

仅支持 FOR EACH ROW 触发器,因此 FOR EACH ROW 文本是可选的。对于 FOR EACH ROW 触发器,如果 WHEN 子句表达式的计算结果为 true,则对导致触发器激发的语句所插入、更新或删除的每个数据库行执行 trigger-step 语句。

如果提供了 WHEN 子句,则仅对 WHEN 子句为 true 的行执行指定为触发器步骤的 SQL 语句。如果未提供 WHEN 子句,则对所有行执行 SQL 语句。

在触发器体(trigger-action 子句)中,受影响表的更改之前值和更改之后值使用特殊的表名 OLD 和 NEW 提供。OLD 和 NEW 表的结构与创建触发器的表的结构匹配。OLD 表包含由触发语句修改或删除的任何行,处于其在触发语句操作之前的状态。NEW 表包含由触发语句修改或创建的任何行,处于其在触发语句操作之后的状态。WHEN 子句和 trigger-step 语句都可访问使用 NEW.column-name 和 OLD.column-name 形式的引用插入、删除或更新的行的值,其中 column-name 是与触发器关联的表中的列的名称。OLD 和 NEW 表引用的可用性取决于触发器所处理的 database-event 类型:

  • INSERT – NEW 引用有效

  • UPDATE – NEW 和 OLD 引用有效

  • DELETE – OLD 引用有效

指定的时间(BEFORE、AFTER 或 INSTEAD OF)确定何时执行与插入、修改或删除关联行有关的 trigger-step 语句。可将 ON CONFLICT 子句指定为 trigger-step 中 UPDATE 或 INSERT 语句的一部分。但是,如果将 ON CONFLICT 子句指定为导致触发器激发的语句的一部分,则改用该冲突处理策略。

除了表触发器外,还可在视图上创建 INSTEAD OF 触发器。如果在某个视图上定义了一个或多个 INSTEAD OF INSERT、INSTEAD OF DELETE 或 INSTEAD OF UPDATE 触发器,则在该视图上执行关联类型的语句(INSERT、DELETE 或 UPDATE)不会被视为错误。在这种情况下,在视图上执行 INSERT、DELETE 或 UPDATE 会导致关联触发器激发。由于触发器是 INSTEAD OF 触发器,因此导致触发器激发的语句不会修改视图的基础表。但是,触发器可用于对基础表执行修改操作。

在具有 INTEGER PRIMARY KEY 列的表上创建触发器时,请牢记一个重要问题。如果 BEFORE 触发器修改要由导致触发器激发的语句更新的行的 INTEGER PRIMARY KEY 列,则不会发生更新。解决方法是创建具有 PRIMARY KEY 列而不是 INTEGER PRIMARY KEY 列的表。

可使用 DROP TRIGGER 语句删除触发器。删除表或视图时,也会自动删除与该表或视图关联的所有触发器。

RAISE() 函数

特殊的 SQL 函数 RAISE() 可用于触发器的 trigger-step 语句中。此函数的语法如下:

raise-function  ::=  RAISE ( ABORT, error-message ) | 
                     RAISE ( FAIL, error-message ) | 
                     RAISE ( ROLLBACK, error-message ) | 
                     RAISE ( IGNORE )

在触发器执行期间调用前三种形式之一时,会执行指定的 ON CONFLICT 处理操作(ABORT、FAIL 或 ROLLBACK),而且当前语句的执行结束。ROLLBACK 被认为是语句执行失败,因此执行其 execute() 方法的 SQLStatement 实例将调度 error (SQLErrorEvent.ERROR) 事件。被调度的事件对象的 error 属性中的 SQLError 对象将其 details 属性设置为在 RAISE() 函数中指定的 error-message。

调用 RAISE(IGNORE) 时,将放弃当前触发器的剩余部分、导致触发器执行的语句和执行的任何后续触发器。不回滚数据库更改。如果导致触发器执行的语句本身是触发器的一部分,则在下一步开始时该触发器程序将继续执行。有关冲突解决算法的详细信息,请参阅 ON CONFLICT(冲突算法)部分。

DROP TRIGGER

DROP TRIGGER 语句删除由 CREATE TRIGGER 语句创建的触发器。

sql-statement  ::=  DROP TRIGGER [IF EXISTS] [database-name.] trigger-name

将从数据库中删除触发器。请注意,在删除其关联表时,会自动删除触发器。

特殊的语句和子句

本部分介绍几个对运行时提供的 SQL 进行扩展的子句,以及可在许多语句、注释和表达式中使用的两个语言元素。

COLLATE

COLLATE 子句在 SELECT、CREATE TABLE 和 CREATE INDEX 语句中使用,指定对值进行比较或排序时使用的比较算法。

sql-statement   ::=  COLLATE collation-name 
collation-name  ::=  BINARY | NOCASE

列的默认排序规则类型是 BINARY。将 BINARY 排序规则用于 TEXT 存储类的值时,通过比较内存中表示值的字节来执行二进制排序规则,而不考虑文本编码。

NOCASE 排序规则序列仅应用于 TEXT 存储类的值。在使用时,NOCASE 排序规则执行不区分大小写的比较。

排序规则序列不用于 NULL、BLOB、INTEGER 或 REAL 类型的存储类。

若要将除 BINARY 之外的排序规则类型用于列,必须将 COLLATE 子句指定为 CREATE TABLE 语句中列定义的一部分。每当对两个 TEXT 值进行比较时,都将按照以下规则使用排序规则序列来确定比较的结果:

  • 对于二进制比较运算符(=、<、>、<= 和 >=),如果任一操作数为列,则列的默认排序规则类型确定用于比较的排序规则序列。如果两个操作数都是列,则左操作数的排序规则类型确定所用的排序规则序列。如果操作数都不是列,则使用 BINARY 排序规则序列。

  • BETWEEN...AND 运算符等效于使用两个包含 >= 和 <= 运算符的表达式。例如,表达式 x BETWEEN y AND z 等效于 x >= y AND x <= z。因此,BETWEEN...AND 运算符按照上述规则来确定排序规则序列。

  • IN 运算符的行为与 = 运算符类似,用于确定要使用的排序规则序列。例如,如果 x 是列,则用于表达式 x IN (y, z) 的排序规则序列是 x 的默认排序规则类型。否则,使用 BINARY 排序规则。

  • 可为属于 SELECT 语句的 ORDER BY 子句明确分配要用于排序操作的排序规则序列。在这种情况下,始终使用显式排序规则序列。否则,如果由 ORDER BY 子句排序的表达式是一个列,则使用列的默认排序规则类型确定排序顺序。如果表达式不是一个列,则使用 BINARY 排序规则序列。

EXPLAIN

EXPLAIN 命令修饰符是 SQL 的非标准扩展。

sql-statement  ::=  EXPLAIN sql-statement

如果 EXPLAIN 关键字出现在任何其他 SQL 语句之前,则结果报告它用于执行命令的虚拟机指令序列,而不是实际执行命令,就像不存在 EXPLAIN 关键字一样。EXPLAIN 功能是一种高级功能,允许开发人员更改 SQL 语句文本以尝试优化性能或调试看起来工作不正常的语句。

ON CONFLICT(冲突算法)

ON CONFLICT 子句不是单独的 SQL 命令。它是可出现在许多其他 SQL 命令中的非标准子句。

conflict-clause     ::=  ON CONFLICT conflict-algorithm 
conflict-clause     ::=  OR conflict-algorithm 
conflict-algorithm  ::=  ROLLBACK | 
                         ABORT | 
                         FAIL | 
                         IGNORE | 
                         REPLACE

ON CONFLICT 子句的第一种形式(使用关键字 ON CONFLICT)用于 CREATE TABLE 语句中。对于 INSERT 或 UPDATE 语句,使用第二种形式(将 ON CONFLICT 替换为 OR)以使语法看起来更自然。例如,语句变为 INSERT OR IGNORE,而不再是 INSERT ON CONFLICT IGNORE。虽然关键字是不同的,但是子句的含义在任一形式中都是相同的。

ON CONFLICT 子句指定用于解决约束冲突的算法。五种算法为 ROLLBACK、ABORT、FAIL、IGNORE 和 REPLACE。默认算法为 ABORT。以下是对这五种冲突算法的说明:

ROLLBACK
出现约束冲突时,会立即发生 ROLLBACK,结束当前的事务。命令将中止,SQLStatement 实例调度 error 事件。如果没有事务处于活动状态(在每个命令上创建的隐含事务除外),则此算法的作用与 ABORT 相同。

ABORT
出现约束冲突时,命令将撤消它之前可能已进行的任何更改,SQLStatement 实例会调度 error 事件。不执行 ROLLBACK,因此将保留以前命令在事务中进行的更改。ABORT 是默认行为。

FAIL
出现约束冲突时,命令将中止,SQLStatement 会调度 error 事件。但是,将保留而不撤消在遇到约束违反之前语句对数据库进行的任何更改。例如,如果 UPDATE 语句在它尝试更新的第 100 行上遇到约束冲突,则保留对前 99 行的更改,但不会更改第 100 行和之后的行。

IGNORE
出现约束冲突时,不插入或更改包含约束冲突的一行。除了忽略此行外,命令通常会继续正常执行。通常会继续正常地插入或更新包含约束违反的行之前和之后的其他行。不返回错误。

REPLACE
出现 UNIQUE 约束冲突时,在插入或更新当前行之前,删除导致约束冲突的预先存在的行。因此,插入或更新会始终进行,而且命令通常会继续正常执行。不返回错误。如果出现 NOT NULL 约束冲突,则将 NULL 值替换为该列的默认值。如果列没有默认值,则使用 ABORT 算法。如果出现 CHECK 约束冲突,则使用 IGNORE 算法。此冲突解决策略删除行以便满足约束时,它不会调用这些行上的删除触发器。

在 INSERT 或 UPDATE 语句的 OR 子句中指定的算法将覆盖在 CREATE TABLE 语句中指定的任何算法。如果未在 CREATE TABLE 语句或者执行 INSERT 或 UPDATE 语句中指定算法,则将使用 ABORT 算法。

REINDEX

REINDEX 命令用于删除并重新创建一个或多个索引。在排序规则序列的定义更改时,此命令很有用。

sql-statement  ::=  REINDEX collation-name 
sql-statement  ::=  REINDEX [database-name .] ( table-name | index-name )

在第一种形式中,将重新创建使用指定排序规则序列的所有附加数据库中的所有索引。在第二种形式中,指定 table-name 时,将重新生成与表关联的所有索引。如果提供了 index-name,则仅删除并重新创建指定的索引。

COMMENTS

注释不是 SQL 命令,但它们可出现在 SQL 查询中。运行时将它们视为空白。它们可从能找到空白的任何位置开始,包括跨多行的表达式的内部。

comment             ::=  single-line-comment | 
                         block-comment 
single-line-comment ::=  -- single-line 
block-comment       ::=  /* multiple-lines or block [*/]

单行注释由两个短划线指示。单行注释仅扩展到当前行的结尾。

块注释可跨任何数目的行,或者嵌入到单行中。如果没有终止分隔符,则块注释可扩展到输入的结尾。此情况并不被视为错误。新的 SQL 语句可在块注释结束后的行上开始。块注释可嵌入到能出现空白的任何位置中,包括表达式内部和其他 SQL 语句的中间。块注释不嵌套。忽略块注释内的单行注释。

EXPRESSIONS

表达式是其他 SQL 块中的子命令。以下介绍 SQL 语句中表达式的有效语法:

expr            ::=  expr binary-op expr | 
                     expr [NOT] like-op expr [ESCAPE expr] | 
                     unary-op expr | 
                     ( expr ) | 
                     column-name | 
                     table-name.column-name | 
                     database-name.table-name.column-name | 
                     literal-value | 
                     parameter | 
                     function-name( expr-list | * ) | 
                     expr ISNULL | 
                     expr NOTNULL | 
                     expr [NOT] BETWEEN expr AND expr | 
                     expr [NOT] IN ( value-list ) | 
                     expr [NOT] IN ( select-statement ) | 
                     expr [NOT] IN [database-name.] table-name | 
                     [EXISTS] ( select-statement ) | 
                     CASE [expr] ( WHEN expr THEN expr )+ [ELSE expr] END | 
                     CAST ( expr AS type ) | 
                     expr COLLATE collation-name 
like-op         ::=  LIKE | GLOB 
binary-op       ::=  see Operators 
unary-op        ::=  see Operators 
parameter       ::=  :param-name | @param-name | ? 
value-list      ::=  literal-value [, literal-value]* 
literal-value   ::=  literal-string | literal-number | literal-boolean | literal-blob | literal-null 
literal-string  ::=  'string value' 
literal-number  ::=  integer | number 
literal-boolean  ::=  true | false 
literal-blob  ::=  X'string of hexadecimal data' 
literal-null  ::=  NULL

表达式是值和可解析为单个值的运算符的任何组合。根据表达式解析为布尔值(true 或 false)还是解析为非布尔值,可将表达式分为两种常规类型。

在几种常见情况下,包括在 WHERE 子句、HAVING 子句、JOIN 子句中的 ON 表达式以及 CHECK 表达式中,表达式必须解析为布尔值。以下类型的表达式满足此条件:

  • ISNULL

  • NOTNULL

  • IN ()

  • EXISTS ()

  • LIKE

  • GLOB

  • 某些函数

  • 某些运算符(特别是比较运算符)

字面值

文本数字值是以整数或浮点数形式书写的。支持科学记数法。.(句点)字符始终用作小数点。

字符串文本是通过用单引号 ' 将字符串括起来指示的。若要在字符串中加入单引号,请在一行中连续放置两个单引号,例如 ''。

布尔文本由值 true 或 false 指示。文本布尔值用于 Boolean 列数据类型。

BLOB 文本是包含十六进制数据且前面有单个 x 或 X 字符的字符串文本,例如 X'53514697465'。

字面值也可以是标记 NULL。

列名

列名可以是在 CREATE TABLE 语句中定义的任何名称或以下特殊标识符之一:ROWID、OID 或 _ROWID_。这些特殊标识符都描述与每个表的每一行关联的唯一随机整数键(“行键”)。如果 CREATE TABLE 语句未定义同名的真正列,则特殊标识符仅引用行键。行键充当只读列。行键可在能使用常规列的任何位置使用,但您不能在 UPDATE 或 INSERT 语句中更改行键的值。SELECT * FROM table 语句在其结果集中不包括行键。

SELECT 语句

SELECT 语句可在表达式中作为 IN 运算符的右操作数,作为纯量(单个结果值)或者作为 EXISTS 运算符的操作数。用作纯量或 IN 运算符的操作数时,SELECT 在其结果中只能具有单个列。允许使用复合 SELECT 语句(通过诸如 UNION 或 EXCEPT 之类的关键字连接)。在使用 EXISTS 运算符时,忽略 SELECT 的结果集中的列。如果存在一个或多个行,则表达式返回 TRUE;如果结果集为空,则返回 FALSE。如果 SELECT 表达式中没有项引用包含查询中的值,则该表达式将在任何其他处理之前计算一次,并在必要时重用结果。如果 SELECT 表达式不包含外部查询(称为相关子查询)中的变量,则 SELECT 在每次需要时都重新进行计算。

当 SELECT 是 IN 运算符的右操作数时,如果左操作数的结果等于 SELECT 语句结果集中的任一值,则 IN 运算符返回 TRUE。可在 IN 运算符前面加上 NOT 关键字以反转测试的意义。

如果 SELECT 出现在表达式内但不是 IN 运算符的右操作数,则 SELECT 结果的第一行将成为表达式中使用的值。如果 SELECT 生成多个结果行,则忽略第一行后的所有行。如果 SELECT 未生成行,则 SELECT 的值为 NULL。

CAST 表达式

CAST 表达式将指定的值的数据类型更改为提供的类型。指定的类型可以是对 CREATE TABLE 语句的列定义中的类型有效的任何非空类型名称。有关详细信息,请参阅数据类型支持。

其他表达式元素

以下部分介绍可在表达式中使用的其他 SQL 元素:

  • 内置函数:聚合函数,标量函数,日期和时间格式函数

  • 运算符

  • 参数

内置函数

内置函数分为以下三种主要类别:
  • 聚合函数

  • 标量函数

  • 日期和时间格式函数

除了这些函数外,还有一个用于提供执行触发器时的错误通知的特殊函数 RAISE()。此函数只能在 CREATE TRIGGER 语句体使用。有关 RAISE() 函数的信息,请参阅 CREATE TRIGGER > RAISE()。

与 SQL 中的所有关键字一样,函数名称不区分大小写。

聚合函数

聚合函数对多行中的值执行操作。这些函数主要在 SELECT 语句中与 GROUP BY 子句一起使用。

AVG(X)

返回一个组中所有非 NULL X 的平均值。看起来不像数字的字符串和 BLOB 值被解释为 0。AVG() 的结果始终是浮点值,即使所有输入都是整数。

COUNT(X) COUNT(*)

第一种形式返回组中不是 NULL 的 X 次数的计数。第二种形式(使用 * 参数)返回组中的总行数。

MAX(X)

返回组中所有值的最大值。通常的排序顺序用于确定最大值。

MIN(X)

返回组中所有值的最小非 NULL 值。通常的排序顺序用于确定最小值。如果组中的所有值都是 NULL,则返回 NULL。

SUM(X)

TOTAL(X)

返回组中所有非 NULL 值的数字和。如果所有值都是 NULL,则 SUM() 返回 NULL,TOTAL() 返回 0.0。TOTAL() 的结果始终是浮点值。如果所有非 NULL 输入都是整数,则 SUM() 的结果是整数值。如果 SUM() 的任一输入不是整数且不是 NULL,则 SUM() 返回浮点值。此值可能是真实和的近似值。

在采用单个参数的上述任一聚合函数中,可在该参数前面加上关键字 DISTINCT。在这种情况下,在将重复的元素传递到聚合函数之前,会对其进行筛选。例如,函数调用 COUNT(DISTINCT x) 返回列 X 的非重复值数目,而不是列 x 中非 NULL 值的总数。

标量函数

标量函数一次对一行上的值进行运算。

ABS(X)

返回参数 X 的绝对值。

COALESCE(X, Y, ...)

返回第一个非 NULL 参数的副本。如果所有参数都为 NULL,则返回 NULL。必须至少有两个参数。

GLOB(X, Y)

此函数用于实现 X GLOB Y 语法。

IFNULL(X, Y)

返回第一个非 NULL 参数的副本。如果两个参数都为 NULL,则返回 NULL。此函数的行为与 COALESCE() 相同。

HEX(X)

该参数被解释为 BLOB 存储类型的值。结果是该值内容的十六进制呈现。

LAST_INSERT_ROWID()

返回通过当前的 SQLConnection 插入到数据库的最后一行的行标识符(生成的主键)。此值与 SQLConnection.lastInsertRowID 属性返回的值相同。

LENGTH(X)

返回 X 的字符串长度(以字符计)。

LIKE(X, Y [, Z])

此函数用于实现 SQL 的 X LIKE Y [ESCAPE Z] 语法。如果存在可选的 ESCAPE 子句,则使用三个参数调用该函数。否则,仅使用两个参数调用它。

LOWER(X)

返回字符串 X 的副本,其中所有字符都已转换为小写形式。

LTRIM(X) LTRIM(X, Y)

返回通过删除 X 左侧的空格而形成的字符串。如果指定了 Y 参数,则函数将从 X 的左侧删除 Y 中的任何字符。

MAX(X, Y, ...)

返回具有最大值的参数。除了数字外,参数还可能是字符串。最大值由定义的排序顺序确定。请注意,当 MAX() 具有 2 个或更多参数时,它是简单函数,而它只有一个参数时则是聚合函数。

MIN(X, Y, ...)

返回具有最小值的参数。除了数字外,参数还可能是字符串。最小值由定义的排序顺序确定。请注意,MIN() 在具有 2 个或更多参数时是简单函数,在只有一个参数时则是聚合函数。

NULLIF(X, Y)

如果参数是不同的,则返回第一个参数,否则返回 NULL。

QUOTE(X)

此例程返回一个字符串,该字符串是其适合于包含到另一 SQL 语句中的参数的值。字符串括在单引号中,并根据需要对内部引号转义。BLOB 存储类作为十六进制文本进行编码。在编写触发器以实现撤消/重做功能时,此函数是很有用的。

RANDOM(*)

返回一个介于 -9223372036854775808 和 9223372036854775807 之间的伪随机整数。此随机值不是强加密的。

RANDOMBLOB(N)

返回一个包含伪随机字节的 N 字节 BLOB。N 应该是一个正整数。此随机值不是强加密的。如果 N 的值为负,则返回单个字节。

ROUND(X) ROUND(X, Y)

将数值 X 舍入到小数点右侧的 Y 位。如果省略 Y 参数,则使用 0。

RTRIM(X) RTRIM(X, Y)

返回通过删除 X 右侧的空格而形成的字符串。如果指定了 Y 参数,则函数将从 X 的右侧删除 Y 中的任何字符。

SUBSTR(X, Y, Z)

返回输入字符串 X 中以第 Y 个字符开头且长度为 Z 个字符的子字符串。X 的最左侧字符是索引位置 1。如果 Y 为负,则通过从右(而不是从左)计数来查找子字符串的第一个字符。

TRIM(X) TRIM(X, Y)

返回通过删除 X 右侧的空格而形成的字符串。如果指定了 Y 参数,则函数将从 X 的右侧删除 Y 中的任何字符。

TYPEOF(X)

返回表达式 X 的类型。可能的返回值有“null”、“integer”、“real”、“text”和“blob”。有关数据类型的详细信息,请参阅数据类型支持。

UPPER(X)

返回已转换为全大写字母的输入字符串 X 的副本。

ZEROBLOB(N)

返回包含 0x00 的 N 字节的 BLOB。

日期和时间格式函数

日期和时间格式函数是一组用于创建带格式的日期和时间数据的标量函数。请注意,这些函数对字符串值和数字值进行运算,并返回字符串值和数字值。这些函数并不预定用于 DATE 数据类型。如果对其声明数据类型为 DATE 的列中的数据使用这些函数,则它们不会像预期的那样工作。

DATE(T, ...)

DATE() 函数返回一个包含日期的字符串,日期格式为 YYYY-MM-DD。第一个参数 (T) 指定在时间格式下找到的格式的时间字符串。可在时间字符串后指定任何数量的修饰符。可在修饰符下找到这些修饰符。

TIME(T, ...)

TIME() 函数返回一个包含时间的字符串,时间格式为 HH:MM:SS。第一个参数 (T) 指定在时间格式下找到的格式的时间字符串。可在时间字符串后指定任何数量的修饰符。可在修饰符下找到这些修饰符。

DATETIME(T, ...)

DATETIME() 函数返回一个包含日期和时间的字符串,日期和时间格式为 YYYY-MM-DD HH:MM:SS。第一个参数 (T) 指定在时间格式下找到的格式的时间字符串。可在时间字符串后指定任何数量的修饰符。可在修饰符下找到这些修饰符。

JULIANDAY(T, ...)

JULIANDAY() 函数返回一个数字,指示自格林尼治标准时间公元前 4714 年 11 月 24 日中午至所提供日期的天数。第一个参数 (T) 指定在时间格式下找到的格式的时间字符串。可在时间字符串后指定任何数量的修饰符。可在修饰符下找到这些修饰符。

STRFTIME(F, T, ...)

STRFTIME() 例程返回根据指定为第一个参数 F 的格式字符串设置格式的日期。格式字符串支持以下替换:

%d - 一月中的某天

%f - 带小数的秒 SS.SSS

%H - 小时 00-24

%j - 一年中的某天 001-366

%J - 儒略历日数

%m - 月份 01-12

%M - 分钟 00-59

%s - 自 1970-01-01 以来的秒数

%S - 秒 00-59

%w - 一周中的某天 0-6(星期日 = 0)

%W - 一年中的某周 00-53

%Y - 年份 0000-9999

%% - %

第二个参数 (T) 指定在时间格式下找到的格式的时间字符串。可在时间字符串后指定任何数量的修饰符。可在修饰符下找到这些修饰符。

时间格式

时间字符串可采用以下任一格式:

YYYY-MM-DD

2007-06-15

YYYY-MM-DD HH:MM

2007-06-15 07:30

YYYY-MM-DD HH:MM:SS

2007-06-15 07:30:59

YYYY-MM-DD HH:MM:SS.SSS

2007-06-15 07:30:59.152

YYYY-MM-DDTHH:MM

2007-06-15T07:30

YYYY-MM-DDTHH:MM:SS

2007-06-15T07:30:59

YYYY-MM-DDTHH:MM:SS.SSS

2007-06-15T07:30:59.152

HH:MM

07:30(日期是 2000-01-01)

HH:MM:SS

7:30:59(日期是 2000-01-01)

HH:MM:SS.SSS

07:30:59:152(日期是 2000-01-01)

目前

当前的日期和时间(按通用协调时间)。

DDDD.DDDD

儒略历日数是一个浮点数。

这些格式中的字符 T 是分隔日期和时间的文本字符“T”。仅包括时间的格式假定日期是 2001-01-01。

修饰符

时间字符串可后跟用于更改日期或更改日期解释的零个或更多个修饰符。可用的修饰符如下:

NNN 天

要添加到时间的天数。

NNN 小时

要添加到时间的小时数。

NNN 分钟

要添加到时间的分钟数。

NNN.NNNN 秒

要添加到时间的秒数和毫秒数。

NNN 月

要添加到时间的月数。

NNN 年

要添加到时间的年数。

一月的开始

将时间后移到一月的开始。

一年的开始

将时间后移到一年的开始。

一天的开始

将时间后移到一天的开始。

工作日 N

将时间前移到指定的工作日。(0 = 星期日,1 = 星期一,依此类推)。

本地时间

将日期转换为本地时间。

utc

将日期转换为通用协调时间。

运算符

SQL 支持大量的运算符(其中包括大多数编程语言中存在的常见运算符)以及 SQL 独有的几个运算符。

常见运算符

在 SQL 块中允许以下二元运算符,它们按从最高到最低的优先顺序列出:

*    /    % 
+    - 
<< >> &     | 
< >=   > >= 
=    ==   !=   <> IN 
AND 
OR

支持的一元前缀运算符是:

 !    ~    NOT

可以认为 COLLATE 运算符是一元后缀运算符。COLLATE 运算符具有最高的优先顺序。它始终比任何一元前缀运算符或任何二元运算符绑定得更紧密。

请注意,等号和不等号运算符各有两个变体。等号可以是 = 或 ==。不等号运算符可以是 != 或 <>。

|| 运算符是字符串串联运算符 — 它将其操作数的两个字符串联接在一起。

运算符 % 输出其左操作数以其右操作数为模的余数。

任何二元运算符的结果都是一个数字值,但给出字符串结果的 || 串联运算符除外。

SQL 运算符

LIKE

LIKE 运算符进行模式匹配比较。

expr     ::=  (column-name | expr) LIKE pattern 
pattern  ::=  '[ string | % | _ ]'

LIKE 运算符右侧的操作数包含模式,而左侧的操作数包含对模式进行匹配的字符串。模式中的百分比符号 (%) 是一个通配符 — 它与字符串中零个或更多个字符的任何序列匹配。模式中的下划线 (_) 与字符串中的任何单个字符匹配。任何其他字符与自身匹配,或与其小写/大写形式匹配(即匹配是以不区分大小写的方式执行的)。(注意:数据库引擎仅识别 7 位拉丁字符的大写/小写形式。因此,对于 8 位 iso8859 字符或 UTF-8 字符,LIKE 运算符区分大小写。例如,表达式 'a' LIKE 'A' 为 TRUE,但是 'æ' LIKE 'Æ' 为 FALSE)。可使用 SQLConnection.caseSensitiveLike 属性更改拉丁字符的区分大小写。

如果存在可选的 ESCAPE 子句,则 ESCAPE 关键字后面的表达式的计算结果必须是一个包含单个字符的字符串。可在 LIKE 模式中使用此字符,与文本百分比或下划线字符进行匹配。转义符后跟百分比符号、下划线或转义符本身分别与字符串中的文本百分比符号、下划线或转义符匹配。

GLOB

GLOB 运算符与 LIKE 类似,但是对其通配符使用 Unix 文件名替换语法。与 LIKE 不同,GLOB 区分大小写。

IN

IN 运算符计算其左操作数是否等于其右操作数(括号中的一组值)中的值之一。

in-expr         ::=  expr [NOT] IN ( value-list ) | 
                     expr [NOT] IN ( select-statement ) | 
                     expr [NOT] IN [database-name.] table-name 
value-list      ::=  literal-value [, literal-value]*

右操作数可以是一组逗号分隔的字面值,也可以是 SELECT 语句的结果。有关将 SELECT 语句用作 IN 操作符的右侧操作数的说明和限制,请参阅表达式中的 SELECT 语句。

BETWEEN...AND

BETWEEN...AND 运算符等效于使用两个包含 >= 和 <= 运算符的表达式。例如,表达式 x BETWEEN y AND z 等效于 x >= y AND x <= z。

NOT

NOT 运算符是一个求反运算符。可在 GLOB、LIKE 和 IN 运算符前面加上 NOT 关键字来反转测试的意义(换句话说,检查一个值是否与指示的模式不匹配)。

参数

参数在表达式中指定占位符,用于在运行时通过将值分配给 SQLStatement.parameters 关联数组来填充的字面值。参数可采用以下三种形式:

?

问号指示一个索引参数。根据参数在语句中的顺序,为其分配数字(从零开始的)索引值。

:AAAA

冒号后跟标识符名称保存名为 AAAA 的命名参数的位置。命名参数也是根据它们在 SQL 语句中的顺序编号的。若要避免混淆,最好避免混合使用命名参数和编号参数。

@AAAA

“at 符号”等效于冒号。

不支持的 SQL 功能

以下是在 Adobe AIR 中不支持的标准 SQL 元素的列表:
FOREIGN KEY 约束
分析但不强制执行 FOREIGN KEY 约束。

触发器
不支持 FOR EACH STATEMENT 触发器(所有触发器都必须为 FOR EACH ROW)。在表上不支持 INSTEAD OF 触发器(仅在视图上允许 INSTEAD OF 触发器)。不支持递归触发器(触发自身的触发器)。

ALTER TABLE
仅支持 ALTER TABLE 命令的 RENAME TABLE 和 ADD COLUMN 变体。其他种类的 ALTER TABLE 操作(如 DROP COLUMN、ALTER COLUMN、ADD CONSTRAINT 等)将被忽略。

嵌套事务
仅允许单个活动事务。

RIGHT 和 FULL OUTER JOIN
不支持 RIGHT OUTER JOIN 或 FULL OUTER JOIN。

可更新的 VIEW
视图是只读的。不能对视图执行 DELETE、INSERT 或 UPDATE 语句。支持在尝试对视图执行 DELETE、INSERT 或 UPDATE 时激发的 INSTEAD OF 触发器,可使用它更新触发器体中的支持表。

GRANT 和 REVOKE
数据库是一个普通的磁盘文件;可应用的访问权限只有基础操作系统的常规文件访问权限。未实现通常在客户端/服务器 RDBMS 上找到的 GRANT 和 REVOKE 命令。

在一些 SQLite 实现中支持以下 SQL 元素和 SQLite 功能,但是在 Adobe AIR 中不支持它们。此功能的大部分可通过 SQLConnection 类的方法获取:
与事务相关的 SQL 元素(BEGIN、END、COMMIT、ROLLBACK)
通过 SQLConnection 类的与事务相关的方法 SQLConnection.begin()、SQLConnection.commit() 和 SQLConnection.rollback() 可使用此功能。

ANALYZE
此功能可通过 SQLConnection.analyze() 方法获取。

ATTACH
此功能可通过 SQLConnection.attach() 方法获取。

COPY
不支持此语句。

CREATE VIRTUAL TABLE
不支持此语句。

DETACH
此功能可通过 SQLConnection.detach() 方法获取。

PRAGMA
不支持此语句。

VACUUM
此功能可通过 SQLConnection.compact() 方法获取。

无法访问系统表
系统表(包括 sqlite_master 及其他具有“sqlite_”前缀的表)在 SQL 语句中不可用。运行时包括一个架构 API,用于提供面向对象的方法来访问架构数据。有关详细信息,请参阅 SQLConnection.loadSchema() 方法。

正则表达式函数(MATCH() 和 REGEX())
这些函数在 SQL 语句中不可用。

以下功能在许多 SQLite 实现和 Adobe AIR 之间是不同的:

索引语句参数
在许多实现中,索引语句参数从 1 开始。但是,在 Adobe AIR 中,索引语句参数是从零开始的(即,为第一个参数指定索引 0,为第二个参数指定索引 1,依此类推)。

INTEGER PRIMARY KEY 列定义
在许多实现中,只有确切定义为 INTEGER PRIMARY KEY 的列才用作表的实际主键列。在这些实现中,使用通常为 INTEGER 的同义词(例如 int)的其他数据类型不会导致将列用作内部主键。但是,在 Adobe AIR 中,int 数据类型(和其他 INTEGER 同义词)将视为完全等同于 INTEGER。因此,定义为 int PRIMARY KEY 的列用作表的内部主键。有关更多信息,请参阅 CREATE TABLE 和列关联部分。

其他 SQL 功能

默认情况下 SQLite 不支持以下列关联类型,但 Adobe AIR 却支持(请注意,与 SQL 中的所有关键字一样,这些数据类型名称不区分大小写):
Boolean
对应于 Boolean 类。

Date
对应于 Date 类。

int
对应于 int 类(等效于 INTEGER 列关联)。

Number
对应于 Number 类(等效于 REAL 列关联)。

Object
对应于 Object 类或可使用 AMF3 序列化和反序列化的任何子类。(这包括大多数类(其中包括自定义类),但是不包括某些类(其中包括显示对象以及将显示对象作为属性包括的对象)。)

String
对应于 String 类(等效于 TEXT 列关联)。

XML
对应于 ActionScript (E4X) XML 类。

XMLList
对应于 ActionScript (E4X) XMLList 类。

在 SQLite 中默认情况下不支持以下字面值,但是在 Adobe AIR 中支持它们:

true
用于表示文本布尔值 true,以处理 BOOLEAN 列。

false
用于表示文本布尔值 false,以处理 BOOLEAN 列。