1. 语法
create-table-stmt
隐藏
CREATE
TEMP
TEMPORARY
TABLE
IF
NOT
EXISTS
schema-name
.
table-name
(
column-def
table-constraint
,
)
table-options
,
AS
select-stmt
column-def
显示
column-name
type-name
column-constraint
column-constraint
显示
CONSTRAINT
name
PRIMARY
KEY
DESC
conflict-clause
AUTOINCREMENT
ASC
NOT
NULL
conflict-clause
UNIQUE
conflict-clause
CHECK
(
expr
)
DEFAULT
(
expr
)
literal-value
signed-number
COLLATE
collation-name
foreign-key-clause
GENERATED
ALWAYS
AS
(
expr
)
VIRTUAL
STORED
conflict-clause
显示
ON
CONFLICT
ROLLBACK
ABORT
FAIL
IGNORE
REPLACE
expr
显示
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
function-arguments
)
filter-clause
over-clause
(
expr
)
,
CAST
(
expr
AS
type-name
)
expr
COLLATE
collation-name
expr
NOT
LIKE
GLOB
REGEXP
MATCH
expr
expr
ESCAPE
expr
expr
ISNULL
NOTNULL
NOT
NULL
expr
IS
NOT
DISTINCT
FROM
expr
expr
NOT
BETWEEN
expr
AND
expr
expr
NOT
IN
(
select-stmt
)
expr
,
schema-name
.
table-function
(
expr
)
table-name
,
NOT
EXISTS
(
select-stmt
)
CASE
expr
WHEN
expr
THEN
expr
ELSE
expr
END
raise-function
filter-clause
显示
function-arguments
显示
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
over-clause
显示
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
显示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
raise-function
显示
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
foreign-key-clause
显示
REFERENCES
foreign-table
(
column-name
)
,
ON
DELETE
SET
NULL
UPDATE
SET
DEFAULT
CASCADE
RESTRICT
NO
ACTION
MATCH
name
NOT
DEFERRABLE
INITIALLY
DEFERRED
INITIALLY
IMMEDIATE
literal-value
显示
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
signed-number
显示
type-name
显示
name
(
signed-number
,
signed-number
)
(
signed-number
)
signed-number
显示
select-stmt
显示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
common-table-expression
显示
table-name
(
column-name
)
AS
NOT
MATERIALIZED
(
select-stmt
)
,
compound-operator
显示
UNION
UNION
INTERSECT
EXCEPT
ALL
expr
显示
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
function-arguments
)
filter-clause
over-clause
(
expr
)
,
CAST
(
expr
AS
type-name
)
expr
COLLATE
collation-name
expr
NOT
LIKE
GLOB
REGEXP
MATCH
expr
expr
ESCAPE
expr
expr
ISNULL
NOTNULL
NOT
NULL
expr
IS
NOT
DISTINCT
FROM
expr
expr
NOT
BETWEEN
expr
AND
expr
expr
NOT
IN
(
select-stmt
)
expr
,
schema-name
.
table-function
(
expr
)
table-name
,
NOT
EXISTS
(
select-stmt
)
CASE
expr
WHEN
expr
THEN
expr
ELSE
expr
END
raise-function
filter-clause
显示
function-arguments
显示
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
literal-value
显示
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
over-clause
显示
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
显示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
raise-function
显示
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
type-name
显示
name
(
signed-number
,
signed-number
)
(
signed-number
)
signed-number
显示
join-clause
显示
table-or-subquery
join-operator
table-or-subquery
join-constraint
join-constraint
显示
USING
(
column-name
)
,
ON
expr
join-operator
显示
NATURAL
LEFT
OUTER
JOIN
,
RIGHT
FULL
INNER
CROSS
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
result-column
显示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery
显示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
window-defn
显示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
显示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
table-constraint
显示
CONSTRAINT
name
PRIMARY
KEY
(
indexed-column
)
conflict-clause
,
UNIQUE
CHECK
(
expr
)
FOREIGN
KEY
(
column-name
)
foreign-key-clause
,
conflict-clause
显示
ON
CONFLICT
ROLLBACK
ABORT
FAIL
IGNORE
REPLACE
expr
显示
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
function-arguments
)
filter-clause
over-clause
(
expr
)
,
CAST
(
expr
AS
type-name
)
expr
COLLATE
collation-name
expr
NOT
LIKE
GLOB
REGEXP
MATCH
expr
expr
ESCAPE
expr
expr
ISNULL
NOTNULL
NOT
NULL
expr
IS
NOT
DISTINCT
FROM
expr
expr
NOT
BETWEEN
expr
AND
expr
expr
NOT
IN
(
select-stmt
)
expr
,
schema-name
.
table-function
(
expr
)
table-name
,
NOT
EXISTS
(
select-stmt
)
CASE
expr
WHEN
expr
THEN
expr
ELSE
expr
END
raise-function
filter-clause
显示
function-arguments
显示
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
literal-value
显示
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
over-clause
显示
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec
显示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
ordering-term
显示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
raise-function
显示
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
type-name
显示
name
(
signed-number
,
signed-number
)
(
signed-number
)
signed-number
显示
foreign-key-clause
显示
REFERENCES
foreign-table
(
column-name
)
,
ON
DELETE
SET
NULL
UPDATE
SET
DEFAULT
CASCADE
RESTRICT
NO
ACTION
MATCH
name
NOT
DEFERRABLE
INITIALLY
DEFERRED
INITIALLY
IMMEDIATE
indexed-column
显示
column-name
COLLATE
collation-name
DESC
expr
ASC
table-options
显示
2. CREATE TABLE 命令
"CREATE TABLE" 命令用于在 SQLite 数据库中创建一个新表。CREATE TABLE 命令指定新表的以下属性
新表的名称。
创建新表所在的数据库。表可以在主数据库、临时数据库或任何附加的数据库中创建。
表中每列的名称。
表中每列的声明类型。
表中每列的默认值或表达式。
要与每列一起使用的默认排序规则。
可选地,表的 PRIMARY KEY。支持单列和复合(多列)主键。
每个表的 SQL 约束集。SQLite 支持 UNIQUE、NOT NULL、CHECK 和 FOREIGN KEY 约束。
可选地,生成列 约束。
该表是否为 WITHOUT ROWID 表。
该表是否受 严格类型检查 约束。
每个 CREATE TABLE 语句都必须为新表指定一个名称。以“sqlite_”开头的表名保留供内部使用。尝试创建名称以“sqlite_”开头的表是错误的。
如果指定了 schema-name ,则它必须是“main”、“temp”或 附加数据库 的名称。在这种情况下,新表将在指定的数据库中创建。如果“TEMP”或“TEMPORARY”关键字出现在“CREATE”和“TABLE”之间,则新表将在临时数据库中创建。指定 schema-name 和 TEMP 或 TEMPORARY 关键字是错误的,除非 schema-name 为“temp”。如果未指定模式名称且不存在 TEMP 关键字,则表将在主数据库中创建。
通常,尝试在数据库中创建新表是错误的,而该数据库已包含同名的表、索引或视图。但是,如果“IF NOT EXISTS”子句作为 CREATE TABLE 语句的一部分指定,并且同名的表或视图已存在,则 CREATE TABLE 命令将没有任何效果(并且不会返回错误消息)。如果由于现有索引而无法创建表,则仍会返回错误,即使指定了“IF NOT EXISTS”子句。
创建与现有 触发器 同名的表不是错误。
表使用 DROP TABLE 语句删除。
2.1. CREATE TABLE ... AS SELECT 语句
"CREATE TABLE ... AS SELECT" 语句根据 SELECT 语句的结果创建并填充数据库表。该表与 SELECT 语句返回的列数相同。每列的名称与 SELECT 语句结果集中相应列的名称相同。每列的声明类型由 SELECT 语句结果集中相应表达式的 表达式关联性 确定,如下所示
表达式关联性 列声明类型 TEXT "TEXT" NUMERIC "NUM" INTEGER "INT" REAL "REAL" BLOB(也称为“NONE”) ""(空字符串)
使用 CREATE TABLE AS 创建的表没有 PRIMARY KEY 也没有任何类型的约束。每列的默认值为 NULL。新表每列的默认排序规则为 BINARY。
使用 CREATE TABLE AS 创建的表最初会填充 SELECT 语句返回的数据行。行被分配连续递增的 rowid 值,从 1 开始,按照 SELECT 语句返回它们的 顺序 。
3. 列定义
除非是 CREATE TABLE ... AS SELECT 语句,否则 CREATE TABLE 包含一个或多个 列定义 ,之后可选地跟随着 表约束 列表。每个列定义都包含列的名称,之后可选地跟随着列的声明类型,然后是一个或多个可选的 列约束 。出于先前语句的目的,在“列约束”的定义中包含 COLLATE 和 DEFAULT 子句,即使这些在某种意义上并不是真正的约束,因为它们不会限制表可能包含的数据。其他约束 - NOT NULL、CHECK、UNIQUE、PRIMARY KEY 和 FOREIGN KEY 约束 - 对表数据施加限制。
表的列数受 SQLITE_MAX_COLUMN 编译时参数限制。表的单行不能存储超过 SQLITE_MAX_LENGTH 字节的数据。这两个限制都可以在运行时使用 sqlite3_limit() C/C++ 接口降低。
3.1. 列数据类型
与大多数 SQL 数据库不同,SQLite 不会根据列的声明类型来限制可以插入列中的数据类型。相反,SQLite 使用 动态类型 。列的声明类型仅用于确定列的 关联性 。
3.2. DEFAULT 子句
DEFAULT 子句指定一个默认值,如果用户在执行 INSERT 时未显式提供值,则使用该默认值。如果列定义没有附加显式 DEFAULT 子句,则该列的默认值为 NULL。显式 DEFAULT 子句可以指定默认值为 NULL、字符串常量、blob 常量、带符号数字或括号内包含的任何常量表达式。默认值也可以是以下特殊的不区分大小写的关键字之一:CURRENT_TIME、CURRENT_DATE 或 CURRENT_TIMESTAMP。出于 DEFAULT 子句的目的,如果表达式不包含子查询、列或表引用、绑定参数 或用双引号而不是单引号括起来的字符串文字,则认为该表达式是常量。
每次通过未为所有表列提供显式值的 INSERT 语句将行插入表时,新行中存储的值将由其默认值确定,如下所示
如果列的默认值为常量 NULL、文本、blob 或带符号数字值,则该值将直接用于新行。
如果列的默认值为括号内的表达式,则该表达式将为插入的每一行评估一次,并将结果用于新行。
如果列的默认值为 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”。
3.3. COLLATE 子句
COLLATE 子句指定排序规则的名称,该排序规则用作列的默认排序规则。如果未指定 COLLATE 子句,则默认排序规则为 BINARY 。
3.4. GENERATED ALWAYS AS 子句
包含 GENERATED ALWAYS AS 子句的列是 生成列 。从 SQLite 版本 3.31.0(2020-01-22)开始支持生成列。有关生成列的功能和限制的详细信息,请参阅 单独的文档 。
3.5. PRIMARY KEY
SQLite 中的每个表最多只能有一个 PRIMARY KEY。如果将 PRIMARY KEY 关键字添加到列定义中,则表的 PRIMARY KEY 由该单列组成。或者,如果 PRIMARY KEY 子句作为 table-constraint 指定,则表的 PRIMARY KEY 由 PRIMARY KEY 子句中指定的列列表组成。PRIMARY KEY 子句必须仅包含列名——在 PRIMARY KEY 的 indexed-column 中使用表达式不受支持。如果在 CREATE TABLE 语句中出现多个 PRIMARY KEY 子句,则会引发错误。对于普通表,PRIMARY KEY 是可选的,但对于 WITHOUT ROWID 表是必需的。
如果表具有单列主键,并且该列的声明类型为“INTEGER”,并且该表不是 WITHOUT ROWID 表,则该列称为 INTEGER PRIMARY KEY 。有关与 INTEGER PRIMARY KEY 相关联的特殊属性和行为的说明,请参阅 下文 。
具有主键的表中的每一行在其主键列中都必须具有唯一的组合值。出于确定主键值唯一性的目的,NULL 值被认为与所有其他值(包括其他 NULL)不同。如果 INSERT 或 UPDATE 语句尝试修改表内容,以便两行或多行具有相同的主键值,则这是约束违规。
根据 SQL 标准,PRIMARY KEY 应始终暗示 NOT NULL。不幸的是,由于某些早期版本中的错误,在 SQLite 中并非如此。除非列是 INTEGER PRIMARY KEY 或表是 WITHOUT ROWID 表或 STRICT 表或列声明为 NOT NULL,否则 SQLite 允许 PRIMARY KEY 列中的 NULL 值。可以修复 SQLite 以符合标准,但这可能会破坏旧版应用程序。因此,已决定仅记录 SQLite 允许大多数 PRIMARY KEY 列中的 NULL 值这一事实。
3.6. UNIQUE 约束
UNIQUE 约束类似于 PRIMARY KEY 约束,只是单个表可以具有任意数量的 UNIQUE 约束。对于表上的每个 UNIQUE 约束,每一行都必须在 UNIQUE 约束标识的列中包含唯一的组合值。出于 UNIQUE 约束的目的,NULL 值被认为与所有其他值(包括其他 NULL)不同。与 PRIMARY KEY 一样,UNIQUE table-constraint 子句必须仅包含列名——在 UNIQUE table-constraint 的 indexed-column 中使用表达式不受支持。
在大多数情况下,UNIQUE 和 PRIMARY KEY 约束通过在数据库中创建唯一索引来实现。(例外情况是 INTEGER PRIMARY KEY 和 WITHOUT ROWID 表上的 PRIMARY KEY。)因此,以下模式在逻辑上是等价的
CREATE TABLE t1(a, b UNIQUE);
CREATE TABLE t1(a, b PRIMARY KEY);
CREATE TABLE t1(a, b); CREATE UNIQUE INDEX t1b ON t1(b);
3.7. CHECK 约束
CHECK 约束可以附加到列定义上,也可以指定为表约束。在实践中,这两者没有区别。每次将新行插入表中或更新现有行时,与每个 CHECK 约束关联的表达式都会被求值并转换为数值,其方式与 CAST 表达式 相同。如果结果为零(整数 0 或实数 0.0),则发生了约束违规。如果 CHECK 表达式求值为 NULL 或任何其他非零值,则不是约束违规。CHECK 约束的表达式不能包含子查询。
CHECK 约束仅在写入表时进行验证,而不是在读取时进行验证。此外,可以使用“PRAGMA ignore_check_constraints=ON; ”语句暂时禁用 CHECK 约束的验证。因此,查询可能会产生违反 CHECK 约束的结果。
3.8. NOT NULL 约束
NOT NULL 约束只能附加到列定义上,不能指定为表约束。毫不奇怪,NOT NULL 约束规定关联的列不能包含 NULL 值。尝试在插入新行或更新现有行时将列值设置为 NULL 会导致约束违规。NOT NULL 约束在查询期间不会被验证,因此即使列被标记为 NOT NULL,如果数据库文件已损坏,对列的查询也可能会产生 NULL 值。
4. 约束执行
约束在 INSERT 和 UPDATE 期间以及通过 PRAGMA integrity_check 和 PRAGMA quick_check 进行检查,有时还会通过 ALTER TABLE 进行检查。查询和 DELETE 语句通常不验证约束。因此,如果数据库文件已损坏(可能是由于外部程序在不通过 SQLite 库的情况下直接更改数据库文件导致的),则查询可能会返回违反约束的数据。例如
CREATE TABLE t1(x INT CHECK( x>3 ));
/* Insert a row with X less than 3 by directly writing into the
** database file using an external program */
PRAGMA integrity_check; -- Reports row with x less than 3 as corrupt
INSERT INTO t1(x) VALUES(2); -- Fails with SQLITE_CORRUPT
SELECT x FROM t1; -- Returns an integer less than 3 in spite of the CHECK constraint
可以使用 PRAGMA ignore_check_constraints=ON; 语句暂时禁用 CHECK 约束的执行。
4.1. 对约束违规的响应
对约束违规的响应由 约束冲突解决算法 决定。每个 PRIMARY KEY、UNIQUE、NOT NULL 和 CHECK 约束都有一个默认的冲突解决算法。PRIMARY KEY、UNIQUE 和 NOT NULL 约束可以通过在其定义中包含 冲突子句 来显式分配另一个默认的冲突解决算法。或者,如果约束定义不包含 冲突子句 ,则默认的冲突解决算法为 ABORT。CHECK 约束的冲突解决算法始终为 ABORT。(出于向后兼容性的原因,表 CHECK 约束允许具有冲突解决子句,但这没有任何作用。)同一表中的不同约束可能具有不同的默认冲突解决算法。有关更多信息,请参阅标题为 ON CONFLICT 的部分。
5. ROWID 和 INTEGER PRIMARY KEY
除了 WITHOUT ROWID 表之外,SQLite 表中的所有行都具有一个 64 位有符号整数键,该键唯一标识表中的行。此整数通常称为“rowid”。可以使用特殊的不区分大小写的名称“rowid”、“oid”或“_rowid_”代替列名来访问 rowid 值。如果表包含名为“rowid”、“oid”或“_rowid_”的用户定义列,则该名称始终引用显式声明的列,不能用于检索整数 rowid 值。
在 WITHOUT ROWID 表中,rowid(以及“oid”和“_rowid_”)被省略。WITHOUT ROWID 表仅在 SQLite 版本 3.8.2 (2013-12-06)及更高版本中可用。缺少 WITHOUT ROWID 子句的表称为“rowid 表”。
rowid 表的数据存储为 B 树结构,其中包含表中每一行的条目,并使用 rowid 值作为键。这意味着通过 rowid 检索或排序记录的速度很快。搜索具有特定 rowid 的记录或搜索具有指定范围内的 rowid 的所有记录的速度大约是通过指定任何其他 PRIMARY KEY 或索引值进行的类似搜索的两倍。
除了下面提到的一个例外情况外,如果 rowid 表的主键由单个列组成,并且该列的声明类型为“INTEGER”(不区分大小写),则该列将成为 rowid 的别名。这样的列通常称为“整数主键”。只有当声明的类型名称完全为“INTEGER”时,PRIMARY KEY 列才会成为整数主键。其他整数类型名称(如“INT”或“BIGINT”或“SHORT INTEGER”或“UNSIGNED INTEGER”)会导致主键列表现为具有整数 亲和性 和唯一索引的普通表列,而不是 rowid 的别名。
上面提到的例外情况是,如果声明类型为“INTEGER”的列的声明包含“PRIMARY KEY DESC”子句,则它不会成为 rowid 的别名,并且不会被归类为整数主键。这种怪异行为并非设计使然。这是由于早期版本的 SQLite 中存在错误。但是,修复该错误可能会导致向后不兼容。因此,保留了原始行为(并进行了记录),因为角落情况下的奇特行为远比兼容性中断要好。这意味着以下三个表声明都会导致列“x”成为 rowid 的别名(整数主键)
CREATE TABLE t(x INTEGER PRIMARY KEY ASC, y, z);
CREATE TABLE t(x INTEGER, y, z, PRIMARY KEY(x ASC));
CREATE TABLE t(x INTEGER, y, z, PRIMARY KEY(x DESC));
但以下声明不会导致“x”成为 rowid 的别名
CREATE TABLE t(x INTEGER PRIMARY KEY DESC, y, z);
可以使用 UPDATE 语句以与任何其他列值相同的方式修改 Rowid 值,可以使用内置别名之一(“rowid”、“oid”或“_rowid_”)或使用整数主键创建的别名。类似地,INSERT 语句可以提供一个值作为插入的每一行的 rowid。与普通的 SQLite 列不同,整数主键或 rowid 列必须包含整数。整数主键或 rowid 列无法保存浮点数、字符串、BLOB 或 NULL。
如果 UPDATE 语句尝试将整数主键或 rowid 列设置为 NULL 或 blob 值,或者设置为无法无损转换为整数的字符串或实数值,则会发生“数据类型不匹配”错误,并且语句将被中止。如果 INSERT 语句尝试将 blob 值或无法无损转换为整数的字符串或实数值插入整数主键或 rowid 列中,则会发生“数据类型不匹配”错误,并且语句将被中止。
如果 INSERT 语句尝试将 NULL 值插入 rowid 或整数主键列,则系统会自动选择一个整数作为 rowid。如何执行此操作的详细说明在 单独 提供。
父键 的 外键约束 不允许使用 rowid。父键必须仅使用命名的列。
此页面上次修改于 2024-03-13 17:43:35 UTC