一、问题及原因

CREATE TABLE IF NOT EXISTS order_record (id INTEGER PRIMARY KEY AUTOINCREMENT,order_id,stock_code,order_type,limit,creat_time);

  尝试使用上边的语句创建一个名为order_record的表时遇到报错,报错信息如下:

near “limit”: syntax error

  出现这个报错,是因为直接在列名称中使用了SQLite的关键字limit,导致解析器混淆了关键字(Keyword)与标识符(Identifier)。经过测试,在已知的146个保留字中,有89个能直接作为名称使用,而另外57个直接作为名称使用则会引起报错(测试结果详见附录)。

  关于SQLite的关键字,可以参考SQLite官网 - Keywords

二、解决方法

1、避免使用关键字作为名称

  SQLite官方不建议使用关键字作为表、索引、列、数据库、用户定义函数、排序规则、虚拟表模块等的名称。
  因为SQLite保留的关键字较多,且随着SQLite未来的更新升级,保留的关键字可能会更多。为了避免潜在的冲突,官方建议尽量不要直接使用任何单个英文单词作为名称。

2、为名称添加引号

  在标准的SQLite语法中,可以通过为名称添加双引号来表示标识符。示例:"limit"

  此外,还可使用方括号、反单引号来表示标识符。示例:[limit]`limit`

  需要注意的是,方括号和反单引号并不属于标准的SQLite语法,而是对MS Access、SQL Server、MySQL的兼容。在未来的SQLite版本中,可能将不再提供对非标准语法的兼容支持。

附录:关键字列表

关键字 能否直接作为名称
ABORT
ACTION
ADD
AFTER
ALL
ALTER
ALWAYS
ANALYZE
AND
AS
ASC
ATTACH
AUTOINCREMENT
BEFORE
BEGIN
BETWEEN
BY
CASCADE
CASE
CAST
CHECK
COLLATE
COLUMN
COMMIT
CONFLICT
CONSTRAINT
CREATE
CROSS
CURRENT
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
DATABASE
DEFAULT
DEFERRABLE
DEFERRED
DELETE
DESC
DETACH
DISTINCT
DO
DROP
EACH
ELSE
END
ESCAPE
EXCEPT
EXCLUDE
EXCLUSIVE
EXISTS
EXPLAIN
FAIL
FILTER
FIRST
FOLLOWING
FOR
FOREIGN
FROM
FULL
GENERATED
GLOB
GROUP
GROUPS
HAVING
IF
IGNORE
IMMEDIATE
IN
INDEX
INDEXED
INITIALLY
INNER
INSERT
INSTEAD
INTERSECT
INTO
IS
ISNULL
JOIN
KEY
LAST
LEFT
LIKE
LIMIT
MATCH
MATERIALIZED
NATURAL
NO
NOTHING
NOTNULL
NULL
NULLS
OF
OFFSET
ON
OR
ORDER
OTHERS
OUTER
OVER
PARTITION
PLAN
PRAGMA
PRECEDING
PRIMARY
QUERY
RAISE
RANGE
RECURSIVE
REFERENCES
REGEXP
REINDEX
RELEASE
RENAME
REPLACE
RESTRICT
RETURNING
RIGHT
ROLLBACK
ROW
ROWS
SAVEPOINT
SELECT
SET
TABLE
TEMP
TEMPORARY
THEN
TIES
TO
TRANSACTION
TRIGGER
UNBOUNDED
UNION
UNIQUE
UPDATE
USING
VACUUM
VALUES
VIEW
VIRTUAL
WHEN
WHERE
WINDOW
WITH
WITHOUT