Adobe AIR 包括一个 SQL 数据库引擎,该引擎使用开放源代码 SQLite 数据库系统,支持具有许多标准 SQL 功能的本地 SQL 数据库。运行时未指定在文件系统上存储数据库数据的方式或位置。每个数据库都完全存储在单个文件中。开发人员可指定在文件系统中存储数据库文件的位置,单个 AIR 应用程序可访问一个或多个单独的数据库(即单独的数据库文件)。
本文档概述了 SQL 语法和对 Adobe AIR 本地 SQL 数据库的数据类型支持。本文档并不用作综合的 SQL 参考,而仅介绍有关 Adobe AIR 支持的 SQL 方言的详细信息。运行时支持大多数符合 SQL-92 标准的 SQL 方言。由于可以通过众多的参考资料、网站、书籍和培训材料来学习 SQL,因此本文档并不用作综合的 SQL 参考或教程。相反,本文档特别侧重于 Apollo AIR 支持的 SQL 语法,以及 SQL-92 和支持的 SQL 方言之间的差异。
本部分包含以下主题:
本部分介绍 Adobe AIR SQL 数据库引擎支持的 SQL 语法。下面所列的各项分别用于说明不同的语句和子句类型、表达式、内置函数和运算符。本部分包含以下主题:
SELECT
、INSERT
、UPDATE
和 DELETE
)CREATE
、ALTER
和 DROP
语句)除了各种语句和表达式的特定语法外,以下是 SQL 语法的一般规则:
数据操作语句是最常用的 SQL 语句。这些语句用于从数据库表检索、添加、修改和删除数据。支持以下数据操作语句:
SELECT
语句用于查询数据库。SELECT
的结果是零行或多行数据,其中每行都具有固定的列数。结果中的列数由 result
列名称或 SELECT
和可选 FROM
关键字之间的表达式列表指定。
任意的表达式都可用作结果。如果结果表达式是 *
,则以所有表的所有列替换该表达式。如果表达式是表名后跟 .*
,则结果是该表中的所有列。
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
。可省略 sort-order
,在此情况下将使用默认值(升序)。有关 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
语句连接为复合语句时,它们从第一个到最后一个进行组合。
有关允许的表达式的定义,请参阅表达式
INSERT
语句有两种基本形式,它用于用数据填充表。
第一种形式(使用 VALUES
关键字)在现有表中创建单个新行。如果未指定 column-list
,则值的数量必须等于表中的列数。如果指定了 column-list
,则值的数量必须与指定列的数量匹配。将用创建表时定义的默认值填充未出现在列的列表中的表列;如果未定义默认值,则使用 NULL
填充。
INSERT
语句的第二种形式从 SELECT
语句提取其数据。如果未指定 column-list
,则 SELECT
的结果中的列数必须与表中的列数完全匹配,或者它必须与在 column-list
中指定的列数完全匹配。在表中为 SELECT
结果的每一行创建一个新项。SELECT
可能是简单的或复合的。有关允许的 SELECT
语句的定义,请参阅 SELECT。
可选的 conflict-algorithm
允许指定要在此命令过程中使用的替代约束冲突解决算法。有关冲突算法的说明和定义,请参阅 ON CONFLICT(冲突算法)。
该语句的两种 REPLACE INTO
形式等效于将标准的 INSERT [OR conflict-algorithm]
形式与 REPLACE
冲突算法一起使用(即 INSERT OR REPLACE...
形式)。
UPDATE
语句用于更改表的一组行中的列值。
UPDATE
中的每个赋值都指定等号左侧的列名和右侧的任意表达式。表达式可能使用其他列的值。所有表达式都是在进行任何赋值之前计算的。有关允许的表达式的定义,请参阅表达式。
WHERE
子句用于限制所更新的行。WHERE
子句表达式必须解析为布尔值。
可选的 conflict-algorithm
允许指定要在此命令过程中使用的替代约束冲突解决算法。有关冲突算法的说明和定义,请参阅 ON CONFLICT(冲突算法)。
delete 命令用于从表中删除记录。
该命令由 DELETE FROM
关键字后跟要从其删除记录的表的名称组成。
如果没有 WHERE
子句,则删除表的所有行。如果提供了 WHERE
子句,则仅删除与表达式匹配的那些行。WHERE
子句表达式必须解析为布尔值。有关允许的表达式的定义,请参阅表达式。
数据定义语句用于创建、修改和删除数据库对象,如表、视图、索引和触发器。支持以下数据定义语句:
CREATE TABLE
语句由关键字 CREATE TABLE
后跟新表的名称以及列定义和约束的列表(在括号中)组成。表名可以是标识符或字符串。
每个列定义都是列的名称后跟该列的数据类型,然后是一个或多个可选的列约束。列的数据类型限制可在该列中存储的数据。如果尝试在具有不同数据类型的列中存储某个值,则运行时会将该值转换为相应的类型(如果可能),或者引发错误。有关其他信息,请参阅数据类型支持部分。
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
的单个列上,则该列将在内部用作表的实际主键。这意味着该列只能保存唯一整数值。如果表没有 INTEGER PRIMARY KEY
列,则在插入行时将自动生成整数键。使用特殊名称 ROWID
、OID
或 _ROWID_
之一,始终可以访问行的主键。可使用这些名称,而不管它是显式声明的 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
命令允许用户重命名现有表或向其添加新列。无法从表中删除列。
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
语句删除使用 CREATE TABLE
语句添加的表。具有指定 table-name
的表就是所删除的表。它将从数据库和磁盘文件中完全删除。无法恢复表。与表关联的所有索引也将被删除。
默认情况下,DROP TABLE
语句不减小数据库文件的大小。将保留数据库中的空白空间,并在后续 INSERT
操作中使用。若要删除数据库中的可用空间,请使用 SQLConnection.clean()
方法。如果在最初创建数据库时 autoClean
参数设置为 true
,则将自动释放空间。
可选的 IF EXISTS
子句抑制表不存在时通常会导致的错误。
CREATE INDEX
命令包含关键字 CREATE INDEX
,后跟新索引的名称、关键字 ON
、之前创建的要编制索引的表的名称,以及表中其值用于索引键的列的名称的带括号列表。
每个列名都可后跟 ASC
或 DESC
关键字以指示排序顺序,但运行时会忽略指定的排序顺序。排序始终按升序执行。
每个列名后面的 COLLATE
子句定义用于该列中文本值的排序规则序列。默认的排序规则序列是在 CREATE TABLE
语句中为该列定义的排序规则序列。如果未指定排序规则序列,则使用 BINARY
排序规则序列。有关 COLLATE
子句和排序规则函数的定义,请参阅 COLLATE。
对于可附加到单个表的索引数没有任何限制。对于索引中的列数也没有限制。
drop index 语句删除使用 CREATE INDEX
语句添加的语句。指定的索引将从数据库文件中完全删除。恢复索引的唯一方法是,重新输入相应的 CREATE INDEX
命令。
默认情况下,DROP INDEX
语句不减小数据库文件的大小。将保留数据库中的空白空间,并在后续 INSERT
操作中使用。若要删除数据库中的可用空间,请使用 SQLConnection.clean()
方法。如果在最初创建数据库时 autoClean
参数设置为 true
,则将自动释放空间。
CREATE VIEW
命令为预定义的 SELECT
语句分配一个名称。此新名称然后可在其他 SELECT
语句的 FROM
子句中使用以代替表名。视图通常用于简化查询,方法是将一组复杂的(和频繁使用的)数据组合到可在其他操作中使用的结构中。
如果在 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
语句删除由 CREATE VIEW
语句创建的视图。
指定的 view-name
是要删除的视图的名称。将从数据库中删除它,但不会修改基础表中的数据。
create trigger 语句用于向数据库架构添加触发器。触发器是在发生指定的数据库事件 (database-event
) 时自动执行的数据库操作 (trigger-action
)。
触发器被指定为只要出现以下条件就会激发:发生特定数据库表的 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
语句删除触发器。删除表或视图时,也会自动删除与该表或视图关联的所有触发器。
特殊的 SQL 函数 RAISE()
可在触发器的 trigger-step
语句中使用。此函数的语法如下:
在触发器执行期间调用前三种形式之一时,会执行指定的 ON CONFLICT
处理操作(ABORT
、FAIL
或 ROLLBACK
),而且当前语句的执行结束。ROLLBACK
被认为是语句执行失败,因此执行其 execute()
方法的 SQLStatement 实例将调度 error
(SQLErrorEvent.ERROR
) 事件。被调度的事件对象的 error
属性中的 SQLError 对象将其 details
属性设置为在 RAISE()
函数中指定的 error-message
。
调用 RAISE(IGNORE)
时,将放弃当前触发器的剩余部分、导致触发器执行的语句和执行的任何后续触发器。不回滚数据库更改。如果导致触发器执行的语句本身是触发器的一部分,则在下一步开始时该触发器程序将继续执行。有关冲突解决算法的详细信息,请参阅 ON CONFLICT(冲突算法)部分。
DROP TRIGGER
语句删除由 CREATE TRIGGER
语句创建的触发器。
将从数据库中删除触发器。请注意,在删除其关联表时,会自动删除触发器。
本部分介绍几个对运行时提供的 SQL 进行扩展的子句,以及可在许多语句、注释和表达式中使用的两个语言元素。本部分中的元素如下:
COLLATE 子句在 SELECT
、CREATE TABLE
和 CREATE INDEX
语句中使用,指定对值进行比较或排序时使用的比较算法。
列的默认排序规则类型是 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
命令修饰符是 SQL 的非标准扩展。
如果 EXPLAIN
关键字出现在任何其他 SQL 语句之前,则结果报告它用于执行命令的虚拟机指令序列,而不是实际执行命令,就像不存在 EXPLAIN
关键字一样。EXPLAIN
功能是一种高级功能,允许开发人员更改 SQL 语句文本以尝试优化性能或调试看起来工作不正常的语句。
ON CONFLICT
子句不是单独的 SQL 命令。它是可出现在许多其他 SQL 命令中的非标准子句。
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
,结束当前的事务。命令将中止,SQLStatement 实例调度 error
事件。如果没有事务处于活动状态(在每个命令上创建的隐含事务除外),则此算法的作用与 ABORT
相同。error
事件。不执行 ROLLBACK
,因此将保留以前命令在事务中进行的更改。ABORT
是默认行为。error
事件。但是,将保留而不撤消在遇到约束违反之前语句对数据库进行的任何更改。例如,如果 UPDATE
语句在它尝试更新的第 100 行上遇到约束违反,则保留对前 99 行的更改,但对第 100 行和之后行的更改不会发生。UNIQUE
约束违反时,在插入或更新当前行之前,删除导致约束违反的预先存在的行。因此,插入或更新会始终进行,而且命令通常会继续正常执行。不返回错误。如果出现 NOT NULL
约束违反,则将 NULL
值替换为该列的默认值。如果列没有默认值,则使用 ABORT
算法。如果出现 CHECK
约束违反,则使用 IGNORE
算法。此冲突解决策略删除行以便满足约束时,它不会调用这些行上的删除触发器。在 INSERT
或 UPDATE
语句的 OR
子句中指定的算法将覆盖在 CREATE TABLE
语句中指定的任何算法。如果未在 CREATE TABLE
语句或者执行 INSERT
或 UPDATE
语句中指定算法,则将使用 ABORT
算法。
REINDEX
命令用于删除并重新创建一个或多个索引。在排序规则序列的定义更改时,此命令很有用。
在第一种形式中,将重新创建使用指定排序规则序列的所有附加数据库中的所有索引。在第二种形式中,指定 table-name
时,将重新生成与表关联的所有索引。如果提供了 index-name
,则仅删除并重新创建指定的索引。
注释不是 SQL 命令,但它们可出现在 SQL 查询中。运行时将它们视为空白。它们可从能找到空白的任何位置开始,包括跨多行的表达式的内部。
单行注释由两个短划线指示。单行注释仅扩展到当前行的结尾。
块注释可跨任何数目的行,或者嵌入到单行中。如果没有终止分隔符,则块注释可扩展到输入的结尾。此情况并不被视为错误。新的 SQL 语句可在块注释结束后的行上开始。块注释可嵌入到能出现空白的任何位置中,包括表达式内部和其他 SQL 语句的中间。块注释不嵌套。忽略块注释内的单行注释。
表达式是其他 SQL 块中的子命令。以下介绍 SQL 语句中表达式的有效语法:
表达式是值和可解析为单个值的运算符的任何组合。根据表达式解析为布尔值(true 或 false)还是解析为非布尔值,可将表达式分为两种常规类型。
在几种常见情况下,包括在 WHERE 子句、HAVING 子句、JOIN 子句中的 ON 表达式以及 CHECK 表达式中,表达式必须解析为布尔值。以下类型的表达式满足此条件:
文本数字值是以整数或浮点数形式书写的。支持科学记数法。.
(句点)字符始终用作小数点。
字符串文本是通过用单引号 '
将字符串括起来指示的。若要将单引号包括在字符串中,请连续放置两个单引号,例如:''
。
布尔文本由值 true
或 false
指示。文本布尔值用于 Boolean 列数据类型。
BLOB 文本是包含十六进制数据且前面有单个 x
或 X
字符的字符串文本,如 X'53514697465'
。
字面值也可以是标记 NULL
。
列名可以是在 CREATE TABLE
语句中定义的任何名称或以下特殊标识符之一:ROWID
、OID
或 _ROWID_
。这些特殊标识符都描述与每个表的每一行关联的唯一随机整数键(“行键”)。如果 CREATE TABLE
语句未定义同名的真正列,则特殊标识符仅引用行键。行键充当只读列。行键可在能使用常规列的任何位置使用,但您不能在 UPDATE
或 INSERT
语句中更改行键的值。SELECT * FROM table
语句在其结果集中不包括行键。
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
表达式将指定的值的数据类型更改为提供的类型。指定的类型可以是对 CREATE TABLE
语句的列定义中的类型有效的任何非空类型名称。有关详细信息,请参阅数据类型支持。
这些部分介绍可在表达式中使用的其他 SQL 元素:
内置函数分为以下三种主要类别:
除了这些函数外,还有一个用于提供执行触发器时的错误通知的特殊函数 RAISE()
。此函数只能在 CREATE TRIGGER
语句体使用。有关 RAISE()
函数的信息,请参阅 CREATE TRIGGER > RAISE()。
与 SQL 中的所有关键字一样,函数名称不区分大小写。
聚合函数对多行中的值执行操作。这些函数主要在 SELECT
语句中与 GROUP BY
子句一起使用。
AVG(X) |
返回一个组中所有非 NULL X 的平均值。看起来不像数字的字符串和 BLOB 值被解释为 0。AVG() 的结果始终是浮点值,即使所有输入都是整数。 |
|
第一种形式返回 X 在组中不是 NULL 的次数的计数。第二种形式(使用 * 参数)返回组中的总行数。 |
MAX(X) |
返回组中所有值的最大值。通常的排序顺序用于确定最大值。 |
MIN(X) |
返回组中所有值的最小非 NULL 值。通常的排序顺序用于确定最小值。如果组中的所有值都是 NULL ,则返回 NULL 。 |
|
返回组中所有非 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 的副本,其中所有字符都已转换为小写形式。 |
|
返回通过删除 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 的值为负,则返回单个字节。 |
|
将数值 X 舍入到小数点右侧的 Y 位。如果省略 Y 参数,则使用 0。 |
|
返回通过删除 X 右侧的空格而形成的字符串。如果指定了 Y 参数,则函数将从 X 的右侧删除 Y 中的任何字符。 |
SUBSTR(X, Y, Z) |
返回输入字符串 X 中以第 Y 个字符开始且长度为 Z 个字符的子字符串。X 的最左侧字符是索引位置 1。如果 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 的格式字符串设置格式的日期。格式字符串支持以下替换:
第二个参数 ( 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 | 07: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 块中允许以下二元运算符,它们按从最高到最低的优先顺序列出:
支持的一元前缀运算符是:
可以认为 COLLATE
运算符是一元后缀运算符。COLLATE
运算符具有最高的优先顺序。它始终比任何一元前缀运算符或任何二元运算符绑定得更紧密。
请注意,等号和不等号运算符各有两个变体。等号可以是 =
或 ==
。不等号运算符可以是 !=
或 <>
。
||
运算符是字符串串联运算符 — 它将其操作数的两个字符串联接在一起。
运算符 %
输出其左操作数以其右操作数为模的余数。
任何二元运算符的结果都是一个数字值,但给出字符串结果的 ||
串联运算符除外。
LIKE
运算符进行模式匹配比较。
LIKE
运算符右侧的操作数包含模式,而左侧的操作数包含对模式进行匹配的字符串。模式中的百分比符号 (%
) 是一个通配符 — 它与字符串中零个或更多个字符的任何序列匹配。模式中的下划线 (_
) 与字符串中的任何单个字符匹配。任何其他字符与自身匹配,或与其小写/大写形式匹配(即匹配是以不区分大小写的方式执行的)。(注意:数据库引擎仅识别 7 位拉丁字符的大写/小写形式。因此,对于 8 位 iso8859 字符或 UTF-8 字符,LIKE
运算符区分大小写。例如,表达式 'a' LIKE 'A'
为 TRUE
,但是 'æ' LIKE 'Æ'
为 FALSE
)。可使用 SQLConnection.caseSensitiveLike
属性更改拉丁字符的区分大小写。
如果存在可选的 ESCAPE
子句,则 ESCAPE
关键字后面的表达式的计算结果必须是一个包含单个字符的字符串。可在 LIKE
模式中使用此字符,与文本百分比或下划线字符进行匹配。转义符后跟百分比符号、下划线或转义符本身分别与字符串中的文本百分比符号、下划线或转义符匹配。
GLOB
运算符与 LIKE
类似,但是对其通配符使用 Unix 文件名替换语法。与 LIKE
不同,GLOB
区分大小写。
IN
运算符计算其左操作数是否等于其右操作数(括号中的一组值)中的值之一。
右操作数可以是一组逗号分隔的字面值,或者它可以是 SELECT
语句的结果。有关将 SELECT 语句用作 IN
操作符的右侧操作数的说明和限制,请参阅表达式中的 SELECT
语句。
BETWEEN...AND
运算符等效于使用两个包含 >=
和 <=
运算符的表达式。例如,表达式 x BETWEEN y AND z
等效于 x >= y AND x <= z
。
NOT 运算符是一个求反运算符。可在 GLOB
、LIKE
和 IN
运算符前面加上 NOT
关键字来反转测试的意义(换句话说,检查一个值是否与指示的模式不匹配)。
参数在表达式中指定占位符,用于在运行时通过将值分配给 SQLStatement.parameters
关联数组来填充的字面值。参数可采用以下三种形式:
? |
问号指示一个索引参数。根据参数在语句中的顺序,为其分配数字(从零开始的)索引值。 |
:AAAA |
冒号后跟标识符名称保存名为 AAAA 的命名参数的位置。命名参数也是根据它们在 SQL 语句中的顺序编号的。若要避免混淆,最好避免混合使用命名参数和编号参数。 |
@AAAA |
“at 符号”等效于冒号。 |
以下是在 Adobe AIR 中不支持的标准 SQL 元素的列表:
FOREIGN KEY
约束。FOR EACH STATEMENT
触发器(所有触发器都必须为 FOR EACH ROW
)。在表上不支持 INSTEAD OF
触发器(仅在视图上允许 INSTEAD OF
触发器)。不支持递归触发器(触发自身的触发器)。ALTER TABLE
命令的 RENAME TABLE
和 ADD COLUMN
变体。其他种类的 ALTER TABLE
操作(如 DROP COLUMN
、ALTER COLUMN
、ADD CONSTRAINT
等)将被忽略。RIGHT OUTER JOIN
或 FULL OUTER JOIN
。DELETE
、INSERT
或 UPDATE
语句。支持在尝试对视图执行 DELETE
、INSERT
或 UPDATE
时激发的 INSTEAD OF
触发器,可使用它更新触发器体中的支持表。GRANT
和 REVOKE
命令。在一些 SQLite 实现中支持以下 SQL 元素和 SQLite 功能,但是在 Adobe AIR 中不支持它们。此功能的大部分可通过 SQLConnection 类的方法获取:
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()
方法获取。SQLConnection.loadSchema()
方法。SQLITE_VERSION()
函数:sqlite_version()
函数在 SQL 语句中不可用。MATCH()
和 REGEX()
):这些函数在 SQL 语句中不可用。以下功能在许多 SQLite 实现和 Adobe AIR 之间是不同的:
在 SQLite 中默认情况下不支持以下列关联类型,但是在 Adobe AIR 中支持它们:
在 SQLite 中默认情况下不支持以下字面值,但是在 Adobe AIR 中支持它们:
true
,以处理 BOOLEAN 列。false
,以处理 BOOLEAN 列。与大多数 SQL 数据库不同,Adobe AIR SQL 数据库引擎不要求或强制表列包含某种类型的值。相反,运行时使用两个概念(存储类和列关联)来控制数据类型。本部分介绍存储类和列关联,以及如何在各种情况下解决数据类型差异:
存储类表示用于在数据库中存储值的实际数据类型。以下存储类是可用的:
NULL
值。对于作为嵌入在 SQL 语句中的文本或使用参数绑定到准备的 SQL 语句的值提供给数据库的所有值,都在执行 SQL 语句之前为其分配存储类。
如果属于 SQL 语句的文本括在单引号或双引号中,则为其分配存储类 TEXT;如果文本被指定为没有小数点或指数的不带引号数字,则分配 INTEGER;如果文本是带有小数点或指数的不带引号数字,则分配 REAL;如果值为 NULL,则分配 NULL。具有存储类 BLOB 的文本是使用 X'ABCD'
表示法指定的。有关详细信息,请参阅表达式中的字面值。
对于作为使用 SQLStatement.parameters
关联数组的参数提供的值,为其分配与绑定的本机数据类型最紧密匹配的存储类。例如,int 值作为 INTEGER 存储类绑定,为 Number 值分配 REAL 存储类,为 String 值分配 TEXT 存储类,为 ByteArray 对象分配 BLOB 存储类。
列的关联是存储在该列中的数据的建议类型。一个值存储在列中(通过 INSERT
或 UPDATE
语句)时,运行时尝试将该值从其数据类型转换为指定的关联。例如,如果将 Date 值(ActionScript 或 JavaScript Date 实例)插入到一个其关联为 TEXT 的列中,则 Date 值在存储于数据库中之前将转换为 String 表示形式(等效于调用对象的 toString()
方法)。如果该值无法转换为指定的关联,则出现错误,且不执行操作。使用 SELECT
语句从数据库中检索值时,它作为对应于关联的类的实例返回,而不管它在被存储时是否已从不同数据类型转换。
如果一个列接受 NULL 值,则 ActionScript 或 JavaScript 值 null
可用作参数值在该列中存储 NULL。当 NULL 存储类值在 SELECT
语句中检索时,它始终作为 ActionScript 或 JavaScript 值 null
返回,而不管列的关联如何。如果一个列接受 NULL 值,则在尝试将值转换成不可为 Null 的类型(如 Number 或 Boolean)之前,始终检查从该列检索的值以确定它们是否为 null
。
为数据库中的每个列分配以下类型关联之一:
具有 TEXT 或 STRING 关联的列使用存储类 NULL、TEXT 或 BLOB 存储所有数据。如果将数字值插入到具有 TEXT 关联的列中,则在存储它之前将它转换为文本形式。
具有 NUMERIC 关联的列包含使用存储类 NULL、REAL 或 INTEGER 的值。将文本数据插入到 NUMERIC 列中时,在存储它之前,会尝试将它转换为整数或实数。如果转换成功,则使用 INTEGER 或 REAL 存储类存储值(例如,值 '10.05'
在被存储之前转换为 REAL 存储类)。如果无法执行转换,则出现错误。不会尝试转换 NULL 值。从 NUMERIC 列检索的值作为该值适合的最具体数字类型的实例返回。换句话说,如果该值是一个正整数或 0,则它作为 uint 实例返回。如果它是一个负整数,则它作为 int 实例返回。最后,如果它具有浮点部分(它不是一个整数),则它作为 Number 实例返回。
使用 INTEGER 关联的列的行为方式与具有 NUMERIC 关联的列相同,但有一处不同。如果要存储的值是一个没有浮点部分的实数值(如 Number 实例),或者如果该值是可转换为没有浮点部分的实数值的文本值,则将它转换为整数并使用 INTEGER 存储类存储它。如果尝试存储具有浮点部分的实数值,则出现错误。
具有 REAL 或 NUMBER 关联的列的行为与具有 NUMERIC 关联的列类似,但是它将整数值强制为浮点表示形式。REAL 列中的值始终作为 Number 实例从数据库返回。
具有 BOOLEAN 关联的列存储 true 或 false 值。BOOLEAN 列接受作为 ActionScript 或 JavaScript Boolean 实例的值。如果代码尝试存储字符串值,则将长度大于零的字符串视为 true,并将空字符串视为 false。如果代码尝试存储数字数据,则任何非零值作为 true 存储,而 0 作为 false 存储。使用 SELECT
语句检索 Boolean 值时,它作为 Boolean 实例返回。非 NULL 值是使用 INTEGER 存储类存储的(0 表示 false,1 表示 true),并在检索数据时转换为 Boolean 对象。
具有 DATE 关联的列存储日期和时间值。DATE 列设计用于接受作为 ActionScript 或 JavaScript Date 实例的值。如果尝试在 DATE 列中存储 String 值,则运行时会尝试将它转换为罗马儒略历日期。如果转换失败,则出现错误。如果代码尝试存储 Number、int 或 uint 值,则不会尝试验证数据,而假定它是有效的罗马儒略历日期值。将使用 SELECT
语句检索的 DATE 值自动转换为 Date 实例。使用 REAL 存储类将 DATE 值存储为罗马儒略历日期值,因此排序和比较操作可以如预期的那样进行。
使用 XML 或 XMLLIST 关联的列存储 XML 结构。当代码尝试使用 SQLStatement 参数在 XML 列中存储数据时,运行时会尝试使用 ActionScript XML()
或 XMLList()
函数转换和验证值。如果该值无法转换为有效的 XML,则出现错误。如果存储数据的尝试使用 SQL 文本字面值(例如 INSERT INTO (col1) VALUES ('
),则不分析或验证该值 — 而是假定它的格式正确。如果存储了无效值,则在检索它时,它作为空的 XML 对象返回。XML 和 XMLLIST 数据是使用 TEXT 存储类或 NULL 存储类存储的。
具有 OBJECT 关联的列存储 ActionScript 或 JavaScript 复杂对象,其中包括 Object 类实例以及 Object 子类的实例(如 Array 实例,甚至是自定义类实例)。OBJECT 列数据以 AMF3 格式进行序列化,并使用 BLOB 存储类进行存储。在检索一个值时,它从 AMF3 进行反序列化,并在被存储时作为类的实例返回。请注意,某些 ActionScript 类(尤其是显示对象)无法反序列化为其原始数据类型的实例。在存储自定义类实例之前,必须使用 flash.net.registerClassAlias()
方法(或者在 Flex 中,通过向类声明添加 [RemoteObject]
元数据)为该类注册一个别名。此外,在检索该数据之前,必须为类注册相同的别名。无法正确进行反序列化的任何数据(因为类本身无法进行反序列化,或者因为缺少类别名或类别名不匹配),在被存储时作为具有对应于原始实例的属性和值的匿名对象(Object 类实例)返回。
对于具有关联 NONE 的列,使用任何存储类都是等效的。它不尝试在插入数据之前将其转换。
列的类型关联由在 CREATE TABLE
语句中声明的列类型确定。在确定类型时,可应用以下规则:
VARCHAR
包含字符串“CHAR”,因此为其分配 TEXT 关联。CREATE TABLE t AS SELECT...
语句创建的,则所有列都未指定数据类型,将为它们分配关联 NONE。支持以下二元比较运算符 =
、<
、<=
、>=
和 !=
,以及测试集合成员身份的运算符 IN
和三元比较运算符 BETWEEN
。有关这些运算符的详细信息,请参阅运算符。
比较的结果取决于所比较的两个值的存储类。在比较两个值时,可应用以下规则:
在数字存储类和文本存储类之间进行二元比较时,在执行比较之前,数据库会根据需要尝试对值进行转换。在比较数字存储类和文本存储类时,可应用以下规则(注意:在以下规则中使用的术语表达式包括除列值外的任何 SQL 标量表达式或文本。例如,如果 X
和 Y.Z
是列名,则认为 +X
和 +Y.Z
是表达式):
始终将三元运算符 BETWEEN
重新转换为等效的二元表达式。例如,a BETWEEN b AND c
将重新转换为 a >= b AND a <= c
,即使这意味着在计算表达式所需的每个比较中将不同的关联应用于 a
。
a IN (SELECT b ....)
类型的表达式由先前为二元比较列举的三个规则处理,即以与 a = b
类似的方式。例如,如果 b
是一个列值,a
是一个表达式,则在进行任何比较之前,将 b
的关联应用于 a
。将表达式 a IN (x, y, z)
重新转换为 a = +x OR a = +y OR a = +z
。IN
运算符右侧的值(此示例中为 x
、y
和 z
值)被视为表达式,即使它们碰巧是列值。如果 IN
左侧的值是一个列,则使用该列的关联。如果该值是一个表达式,则不发生转换。
执行比较的方式也会受到使用 COLLATE
子句的影响。有关详细信息,请参阅 COLLATE。
对于每个支持的数学运算符(*
、/
、%
、+
和 -
),在计算表达式之前,会将数字关联应用于每个操作数。如果任一操作数无法成功转换为 NUMERIC 存储类,则表达式的计算结果将为 NULL
。
如果使用了串联运算符 ||
,则在计算表达式之前将每个操作数转换为 TEXT 存储类。如果任一操作数无法转换为 TEXT 存储类,则表达式的结果为 NULL
。在两种情况下可能发生无法转换值的此问题:操作数的值为 NULL
,或者它是包含非 TEXT 存储类的 BLOB。
通过 ORDER BY
子句对值排序时,具有存储类 NULL 的值排在最前面。它们后跟按数字顺序散布的 INTEGER 和 REAL 值,再后跟按二进制顺序或基于指定排序规则(BINARY
或 NOCASE
)的 TEXT 值。最后是按二进制顺序的 BLOB 值。在排序之前,不发生存储类转换。
使用 GROUP BY
子句对值分组时,将具有不同存储类的值视为非重复。例外是 INTEGER 和 REAL 值,如果它们在数值上相等,则认为它们相等。GROUP BY
子句不会导致将关联应用于任何值。
复合 SELECT
运算符 UNION
、INTERSECT
和 EXCEPT
执行值之间的隐式比较。在执行这些比较之前,可能会将关联应用于每个值。相同的关联(如果有)将应用于在复合 SELECT
结果集的单个列中可能返回的所有值。所应用的关联是在该位置中具有列值(而不是其他某种表达式)的第一个构成性 SELECT
语句所返回的列的关联。如果对于给定的复合 SELECT
列,构成性 SELECT
语句都不返回列值,则在对该列中的值进行比较之前,不将关联应用于这些值。
在本文档的语句定义中,使用了以下约定:
UPPER CASE
- 文本 SQL 关键字以全大写形式书写lower case
- 占位符项或子句名称以全小写形式书写::=
- 指示一个子句或语句定义|
- 管道字符在替代选项之间使用,可读作“或”[]
- 方括号中的项是可选项;括号中可包含单个项或一组替代项()
- 括住一组替代项(一组由管道字符分隔的项)的圆括号指定一组必需项,即作为单个必需项的可能值的一组项
数量表示符
+
- 圆括号中的项后面的加号字符指示前面的项可出现 1 次或更多次*
- 方括号中的项后面的星号字符指示前面的(在括号中的)项可出现 0 次或更多次*
- 在列名中或函数名称后面的圆括号之间使用的星号,表示文本星号字符,而不是“0 个或更多个”数量表示符.
- 句点字符表示文本句点,
- 逗号字符表示文本逗号()
- 括住单个子句或项的一对圆括号指示圆括号是必需的文本圆括号字符。