SQLite的SQL语法

SQLite库能够解析大部分标准SQL语言。但它也省去了一些特性而且增加了一些自己的新特性。这篇文档就是试图描写叙述那些SQLite支持/不支持的SQL语法的。查看keyword列表

例如以下语法表格中,纯文本用蓝色粗体显示。非终极符号为斜体红色。作为语法一部分的运算符用黑色Roman字体表示。

这篇文档仅仅是对SQLite实现的SQL语法的综述,有所忽略。想要得到更具体的信息,參考源码和语法文件“parse.y”。

SQLite运行例如以下的语法:

ALTER TABLE

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

SQLite版本号的的ALTER TABLE命令同意用户重命名或加入新的字段到已有表中,不能从表中删除字段。

RENAME TO语法用于重命名表名[database-name.]table-namenew-table-name。这一命令不能用于在附加数据库之间移动表,仅仅能在同一个数据库中对表进行重命名。

若须要重命名的表有触发器或索引,在重命名后它们依旧属于该表。但若定义了视图,或触发器运行的语句中有提到 表的名字,则它们不会被自己主动改为使用新的表名。若要进行这一类的改动,则需手工撤销并使用新的表名重建触发器或视图。

ADD [COLUMN]语法用于在已有表中加入新的字段。新字段总是加入到已有字段列表的末尾。Column-def能够是CREATE TABLE中同意出现的不论什么形式,且须符合例如以下限制:

  • 字段不能有主键或唯一约束。
  • 字段不能有这些缺省值:CURRENT_TIME, CURRENT_DATE或CURRENT_TIMESTAMP
  • 若定义了NOT NULL约束,则字段必须有一个非空的缺省值。

ALTER TABLE语句的执行时间与表中的数据量无关,它在操作一个有一千万行的表时的执行时间与操作仅有一行的表时是一样的。

在对数据库执行ADD COLUMN之后,该数据库将无法由SQLite 3.1.3及更早版本号读取,除非执行VACUUM命令。

ANALYZE

sql-statement ::= ANALYZE
sql-statement ::= ANALYZE database-name
sql-statement ::= ANALYZE [database-name .] table-name

ANALYZE命令令集合关于索引的统计信息并将它们储存在数据库的一个特殊表中,查询优化器能够用该表来制作更好的索引选择。若不给出參数,全部附加数据库中的全部索引被分析。若參数给出数据库名,该数据库中的全部索引被分析。若给出表名 作參数,则仅仅有关联该表的索引被分析。

最初的实现将全部的统计信息储存在一个名叫sqlite_stat1的表中。未来的加强版本号中可能会创建名字相似的其他表,仅仅是把“1”改为其他数字。sqlite_stat1表不可以被撤销,但当中的全部内容可以被删除,这是与撤销该表等效的行为。

ATTACH DATABASE

ATTACH DATABASE语句将一个已存在的数据库加入到当前数据库连接。若文件名称含标点符号,则应用引號引起来。数据库名’main’和’temp’代表主数据库和用于存放暂时表的数据库,它们不能被拆分。拆分数据库使用DETACH DATABASE语句。

你能够读写附加数据库,或改变其结构。这是SQLite 3.0提供的新特性。在SQLite 2.8中,改变附加数据库的结构是不同意的。

在附加数据库中加入一个与已有表同名的表是不同意的。但你能够附加带有与主数据库中的表同名的表的数据库。也能够多次附加同一数据库。

使用database-name.table-name来引用附加数据库中的表。若附加数据库中的表与主数据库的表不重名,则不需加数据库名作为前缀。当数据库被附加时,它的全部不重名的表成为该名字指向的缺省表。之后附加的随意与之同名的表须要加前缀。若“缺省”表被拆分,则最后附加的同名表变为“缺省”表。

若主数据库不是“:memory:”,多附加数据库的事务是原子的。若主数据库是“:memory:”则事务在每一个独立文件里依旧是原子的。但若主机在改变两个或很多其它数据库的COMMIT语句进行时崩溃,则可能一部分文件被改变而其它的保持原样。附加数据库的原子性的提交 是SQLite 3.0的新特性。在SQLite 2.8中,全部附加数据库的提交相似于主数据库是“:memory:”时的情况。

对附加数据库的数目有编译时的限制,最多10个附加数据库。

BEGIN TRANSACTION

sql-statement ::= BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] [TRANSACTION [name]]
sql-statement ::= END [TRANSACTION [name]]
sql-statement ::= COMMIT [TRANSACTION [name]]
sql-statement ::= ROLLBACK [TRANSACTION [name]]

从2.0版開始,SQLite支持带有回退和原子性的提交的事务处理。

可选的事务名称会被忽略。SQLite眼下不同意嵌套事务。

在事务之外,不能对数据库进行更改。假设当前没有有效的事务,不论什么改动数据库的命令(基本上除了SELECT以外的全部SQL命令)会自己主动启动一个事务。命令结束时,自己主动启动的事务会被提交。

能够使用BEGIN命令手动启动事务。这样启动的事务会在下一条COMMIT或ROLLBACK命令之前一直有效。但若数据库关闭或出现错误且选用ROLLBACK冲突判定算法时,数据库也会ROLLBACK。查看ON CONFLICT子句获取很多其它关于ROLLBACK冲突判定算法的信息。

在SQLite 3.0.8或更高版本号中,事务能够是延迟的,即时的或者独占的。“延迟的”即是说在数据库第一次被訪问之前不获得锁。这样就会延迟事务,BEGIN语句本身不做不论什么事情。直到初次读取或訪问数据库时才获取锁。对数据库的初次读取创建一个SHARED锁 ,初次写入创建一个RESERVED锁。因为锁的获取被延迟到第一次须要时,别的线程或进程能够在当前线程运行BEGIN语句之后创建另外的事务 写入数据库。若事务是即时的,则运行BEGIN命令后马上获取RESERVED锁,而不等数据库被使用。在运行BEGIN IMMEDIATE之后,你能够确保其他的线程或进程不能写入数据库或运行BEGIN IMMEDIATE或BEGIN EXCLUSIVE,但其他进程能够读取数据库。独占事务在全部的数据库获取EXCLUSIVE锁,在运行BEGIN EXCLUSIVE之后,你能够确保在当前事务结束前没有不论什么其他线程或进程 能够读写数据库。

有关SHARED、RESERVED和EXCLUSIVE锁能够參见这里

SQLite 3.0.8的默认行为是创建延迟事务。SQLite 3.0.0到3.0.7中延迟事务是唯一可用的事务类型。SQLite 2.8或更早版本号中,全部的事务都是独占的。

COMMIT命令在所有SQL命令完毕之前并不作实际的提交工作。这样若两个或很多其它个SELECT语句在进程中间而运行COMMIT时,仅仅有所有SELECT语句结束才进行提交。

运行COMMIT可能会返回SQLITE_BUSY错误代码。这就是说有另外一个线程或进程获取了数据库的读取锁,并阻止数据库被改变。当COMMIT获得该错误代码时,事务依旧是活动的,而且在COMMIT能够在当前读取的线程读取结束后再次试图读取数据库。

END TRANSACTION

sql-statement ::= BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] [TRANSACTION [name]]
sql-statement ::= END [TRANSACTION [name]]
sql-statement ::= COMMIT [TRANSACTION [name]]
sql-statement ::= ROLLBACK [TRANSACTION [name]]

从2.0版開始,SQLite支持带有回退和原子性的提交的事务处理。

可选的事务名称会被忽略。SQLite眼下不同意嵌套事务。

在事务之外,不能对数据库进行更改。假设当前没有有效的事务,不论什么改动数据库的命令(基本上除了SELECT以外的全部SQL命令)会自己主动启动一个事务。命令结束时,自己主动启动的事务会被提交。

能够使用BEGIN命令手动启动事务。这样启动的事务会在下一条COMMIT或ROLLBACK命令之前一直有效。但若数据库关闭或出现错误且选用ROLLBACK冲突判定算法时,数据库也会ROLLBACK。查看ON CONFLICT子句获取很多其它关于ROLLBACK冲突判定算法的信息。

在SQLite 3.0.8或更高版本号中,事务能够是延迟的,即时的或者独占的。“延迟的”即是说在数据库第一次被訪问之前不获得锁。这样就会延迟事务,BEGIN语句本身不做不论什么事情。直到初次读取或訪问数据库时才获取锁。对数据库的初次读取创建一个SHARED锁,初次写入创建一个RESERVED锁。因为锁的获取被延迟到第一次须要时,别的线程或进程能够在当前线程运行BEGIN语句之后创建另外的事务写入数据库。若事务是即时的,则运行BEGIN命令后马上获取RESERVED锁,而不等数据库被使用。在运行BEGIN IMMEDIATE之后,你能够确保其他的线程或进程不能写入数据库或运行BEGIN IMMEDIATE或BEGIN EXCLUSIVE,但其他进程能够读取数据库。独占事务在全部的数据库获取EXCLUSIVE锁,在运行BEGIN EXCLUSIVE之后,你能够确保在当前事务结束前没有不论什么其他线程或进程能够读写数据库。

有关SHARED、RESERVED和EXCLUSIVE锁能够參见这里

SQLite 3.0.8的默认行为是创建延迟事务。SQLite 3.0.0到3.0.7中延迟事务是唯一可用的事务类型。SQLite 2.8或更早版本号中,全部的事务都是独占的。

COMMIT命令在所有SQL命令完毕之前并不作实际的提交工作。这样若两个或很多其它个SELECT语句在进程中间而运行COMMIT时,仅仅有所有SELECT语句结束才进行提交。

运行COMMIT可能会返回SQLITE_BUSY错误代码。这就是说有另外一个线程或进程获取了数据库的读取锁,并阻止数据库被改变。当COMMIT获得该错误代码时,事务依旧是活动的,而且在COMMIT能够在当前读取的线程读取结束后再次试图读取数据库。

凝视

comment ::= SQL-comment | C-comment
SQL-comment ::= -- single-line
C-comment ::= /* multiple-lines [*/]

凝视不是SQL命令,但会出如今SQL查询中。它们被解释器处理为空白部分。它们能够在不论什么空白可能存在的地方開始 ,即使是在跨越多行的表达式中。

SQL风格的凝视仅对当前行有效。

C风格的凝视能够跨越多行。若没有结束符号,凝视的范围将一直延伸到输入末尾,且不会引起报错。新的SQL语句能够从多行凝视结束的地方開始。C风格凝视能够嵌入不论什么空白能够出现的地方,包含表达式内,或其它SQL语句中间, 而且C风格的凝视不互相嵌套。SQL风格的凝视出如今C风格凝视中时将被忽略。

COPY

sql-statement ::= COPY [ OR conflict-algorithm ] [database-name .] table-name FROM filename
[ USING DELIMITERS delim ]

COPY命令在SQLite 2.8及更早的版本号中可用。SQLite 3.0删除了这一命令,由于在混合的UTF-8/16环境中对它进行支持是非常复杂的。在3.0版本号中,命令行解释器包括新的.import命令,用以替代COPY。

COPY命令是用于将大量数据插入表的一个插件。它模仿PostgreSQL中的同样命令而来。其实,SQLite的COPY 命令就是为了可以读取PostgreSQL的备份工具pg_dump的输出从而可以将PostgreSQL的数据轻松转换到SQLite中而设计的。

table-name是将要导入数据的一个已存在的表的名字。filename是一个字符串或标识符,用于说明作为数据来源的文件。filename能够使用STDIN从标准输入流中获取数据。

输入文件的每一行被转换成一条单独的记录导入表中。字段用制表符分开。若某个字段的数据中出现制表符,则前面被加入反斜线“/”符号。数据中的反斜线则被替换为两条反斜线。可选的USING DELIMITERS子句可给出一个与制表符不同 的分界符。

若字段由“/N”组成,则被赋以空值NULL。

使用这一命令时,利用可选的ON CONFLICT子句能够定义替代的约束冲突判定算法。很多其它信息,參见 ON CONFLICT

当输入数据源是STDIN,输入将终止于一行仅包括一个反斜线和一个点的输入:“/.”。

CREATE INDEX

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 ]

CREATE INDEX命令由“CREATE INDEX”keyword后跟新索引的名字,keyword“ON”,待索引表的名字,以及括弧内的用于索引键的字段列表构成。每一个字段名能够尾随“ASC”或“DESC”keyword说明排序法则,但在当前版本号中排序法则被忽略。排序总是依照上升序。

每一个字段名后跟COLLATE子句定义文本记录的比較顺序。缺省的比較顺序是由CREATE TABLE语句说明的比較顺序。若不定义比較顺序,则使用内建的二进制比較顺序。

附加到单个表上的索引数目没有限制,索引中的字段数也没有限制。

若UNIQUEkeyword出如今CREATE和INDEX之间,则不同意重名的索引记录。试图插入重名记录将会导致错误。

每条CREATE INDEX语句的文本储存于sqlite_mastersqlite_temp_master表中,取决于被索引的表是否暂时表。 每次打开数据库时,全部的CREATE INDEX语句从sqlite_master表中读出,产生SQLite的索引样式的内部结构。

若使用可选的IF NOT EXISTS子句,且存在同名索引,则该命令无效。

使用DROP INDEX命令删除索引。

CREATE TABLE

sql-command ::= CREATE [TEMP | TEMPORARY] TABLE [IF NOT EXISTS] table-name (
    
column-def [, column-def]*
    
[, constraint]*
)
sql-command ::= 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
value |
COLLATE
collation-name
constraint ::= PRIMARY KEY ( column-list ) [ conflict-clause ] |
UNIQUE (
column-list ) [ conflict-clause ] |
CHECK (
expr )
conflict-clause ::= ON CONFLICT conflict-algorithm

CREATE TABLE语句基本上就是“CREATE TABLE”keyword后跟一个新的表名以及括号内的一堆定义和约束。表名能够是字符串或者标识符。以“sqlite_”开头的表名是留给数据库引擎使用的。

每一个字段的定义是字段名后跟字段的数据类型,接着是一个或多个的字段约束。字段的数据类型并不限制字段中能够存放的数据。能够查看SQLite3的数据类型获取很多其它信息。UNIQUE约束为指定的字段创建索引,该索引须含有唯一键。COLLATE子句说明在比較字段的 文字记录时所使用的排序函数。缺省使用内嵌的BINARY排序函数。

DEFAULT约束说明在使用INSERT插入字段时所使用的缺省值。该值能够是NULL,字符串常量或一个数。从3.1.0版開始,缺省值也能够是下面特殊的与事件无关的keywordCURRENT_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索引。然而,若主键定义在单一的INTEGER类型的字段上,则该字段在内部被用作表的B-Tree键。这即是说字段仅能容纳唯一整数值。(在除此之外的其他情况下,SQLite忽略数据类型的说明 ,同意不论什么类型的数据放入字段中,无论该字段被声明为什么数据类型。)若一个表中不含一个INTEGER PRIMARY KEY字段,则B-Tree键为自己主动产生的整数。一行的B-Tree键能够通过例如以下特殊的名字“ROWID”、“OID”或“_ROWID_”进行訪问,不论是否有INTEGER PRIMARY KEY存在。INTEGER PRIMARY KEY字段能够使用keywordAUTOINCREMENT声明。AUTOINCREMENTkeyword改动了B-Tree键自己主动产生的方式。B-Tree键的生成的其他信息能够在这里找到。

若“TEMP”或“TEMPORARY”keyword出如今“CREATE”和“TABLE”之间,则所建立的表仅在当前数据库连接可见,并在断开连接时自己主动被删除。在暂时表上建立的不论什么索引也是暂时的。暂时表和索引单独存储在与主数据库文件不同的文件里。

若说明了,则表在该数据库中被创建。同一时候声明和TEMPkeyword会出错,除非 是“temp”。若不声明数据库名,也不使用TEMPkeyword,则表创建于主数据库中。

在每一个约束后跟可选的ON CONFLICT子句能够定义替代的约束冲突判定算法。 缺省为ABORT。同一个表中的不同约束能够使用不同的缺省冲突判定算法。若一条COPY、INSERT或UPDATE命令指定了不同的冲突判定算法,则该算法将替代CREATE TABLE语句中说明的缺省算法。很多其它信息,參见ON CONFLICT

3.3.0版支持CHECK约束。在3.3.0之前,CHECK约束被解析但不运行。

表中的字段数或约束数没有不论什么限制。在2.8版中,单行数据的总数被限制为小于1 megabytes。而在3.0中则消除了限制。

CREATE TABLE AS形式定义表为一个查询的结果集。表的字段名字即是结果中的字段名字。

每条CREATE TABLE语句的文本都储存在sqlite_master表中。每当数据库被打开,全部的CREATE TABLE语句从 sqlite_master表中读出,构成表结构的SQLite内部实现。若原始命令为CREATE TABLE AS则合成出等效的CREATE TABLE语句并储存于sqlite_master表中取代原命令。CREATE TEMPORARY TABLE语句文本储存于sqlite_temp_master表中。

若在命令中使用可选的IF NOT EXISTS子句且存在同名的还有一个表,则当前的命令无效。

删除表能够使用DROP TABLE语句。

 

CREATE TRIGGER

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

CREATE TRIGGER语句用于向数据库schema中加入触发器。触发器是一些在特定的数据库事件(database-event)发生时自己主动进行的数据库操作(trigger-action)。

触发器可由在特殊表上运行的DELETE、INSERT、UPDATE等语句触发,或UPDATE表中特定的字段时触发。

如今SQLite仅支持FOR EACH ROW触发器,不支持FOR EACH STATEMENT触发。因此能够不用明白说明FOR EACH ROW。FOR EACH ROW的意思是由trigger-steps说明的SQL语句可能在(由WHEN子句决定的)数据库插入,更改或删除的每一行触发trigger。

WHEN子句和trigger-steps能够使用“NEW.column-name”和“OLD.column-name”的引用形式訪问正在被插入,更改或删除的行的元素,column-name是触发器关联的表中的字段名。OLD和NEW引用仅仅在触发器与之相关的trigger-event处可用,比如:

INSERT NEW可用
UPDATE NEW和OLD均可用
DELETE OLD可用

当使用WHEN子句,trigger-steps仅仅在WHEN子句为真的行运行。不使用WHEN时则在全部行运行。

trigger-time决定了trigger-steps运行的时间,它是相对于关联行的插入、删除和改动而言的。

作为的一部分trigger-step的UPDATE或INSERT能够使用ON CONFLICT子句。但若触发trigger的语句使用了ON CONFLICT子句,则覆盖前述的ON CONFLICT子句所定义的冲突处理方法。

关联表被撤销时触发器被自己主动删除。

不仅在表上,在视图上一样能够创建触发器,在CREATE TRIGGER语句中使用INSTEAD OF就可以。若视图上定义了一个或多个ON INSERT、ON DELETE、ON UPDATE触发器,则对应地对视图运行INSERT、DELETE或UPDATE语句不会出错,而会触发关联的触发器。视图关联的表不会被改动。(除了由触发器进行的改动操作)。

样例:

如果“customers”表存储了客户信息,“orders”表存储了订单信息,以下的触发器确保当用户改变地址时全部的关联订单地址均进行对应改变:

 
CREATE TRIGGER update_customer_address UPDATE OF address ON customers    
    BEGIN 
      UPDATE orders SET address = new.address WHERE customer_name = old.name; 
    END; 

定义了该触发器后运行例如以下语句:

 
UPDATE customers SET address = ’1 Main St.’ WHERE name = ’Jack Jones’; 

会使以下的语句自己主动运行:

 
UPDATE orders SET address = ’1 Main St.’ WHERE customer_name = ’Jack Jones’; 

注意,眼下在有INTEGER PRIMARY KEY域的表上触发器可能工作不正常。若BEFORE触发器改动了一行的INTEGER PRIMARY KEY域,而该域将由触发该触发器的语句进行改动,则可能根本不会改动该域。能够用PRIMARY KEY字段取代INTEGER PRIMARY KEY字段来解决上述问题。

一个特殊的SQL函数RAISE()可用于触发器程序,使用例如以下语法:

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

当触发器程序运行中调用了上述前三个之中的一个的形式时,则运行指定的ON CONFLICT进程(ABORT、FAIL或者ROLLBACK)且终止当前查询,返回一个SQLITE_CONSTRAINT错误并说明错误信息。

当调用RAISE(IGNORE),当前触发器程序的余下部分,触发该触发器的语句和不论什么之后的触发器程序被忽略而且不恢复对数据库的已有改变。若触发触发器的语句是一个触发器程序本身的一部分,则原触发器程序从下一步起继续运行。

使用DROP TRIGGER删除触发器。

CREATE VIEW

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

CREATE VIEW命令为一个包装好的SELECT语句命名。当创建了一个视图,它能够用于其它SELECT的FROM字句中取代表名。

若“TEMP”或“TEMPORARY”keyword出如今“CREATE”和“VIEW”之间,则创建的视图仅对打开数据库的进程可见,且在数据库关闭时自己主动删除。

若指定了则视图在指定的数据库中创建。同一时候使用和TEMPkeyword会导致错误,除非是“temp”。若不声明数据库名,也不使用TEMPkeyword,则视图创建于主数据库中。

你不能对视图使用COPY、DELETE、INSERT或UPDATE,视图在SQLite中是仅仅读的。多数情况下你能够在视图上创建TRIGGER来达到同样目的。用DROP VIEW命令来删除视图。

DELETE

sql-statement ::= DELETE FROM [database-name .] table-name [WHERE expr]

DELETE命令用于从表中删除记录。命令包括“DELETE FROM”keyword以及须要删除的记录所在的表名。

若不使用WHERE子句,表中的所有行将所有被删除。否则仅删除符合条件的行。

DETACH DATABASE

sql-command ::= DETACH [DATABASE] database-name

该语句拆分一个之前使用ATTACH DATABASE语句附加的数据库连接。能够使用不同的名字多次附加同一数据库,而且拆分一个连接不会影响其它连接。

若SQLite在事务进行中,该语句不起作用。

DROP INDEX

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

DROP INDEX语句删除由CREATE INDEX语句创建的索引。索引将从数据库结构和磁盘文件里全然删除,唯一的恢复方法是又一次输入对应的CREATE INDEX命令。

DROP TABLE语句在缺省模式下不减小数据库文件的大小。空间会留给后来的INSERT语句使用。要释放删除产生的空间,能够使用VACUUM命令。若AUTOVACUUM模式开启,则空间会自己主动被DROP INDEX释放。

DROP TABLE

sql-command ::= DROP TABLE [IF EXISTS] [database-name.] table-name

DROP TABLE语句删除由CREATE TABLE语句创建的表。表将从数据库结构和磁盘文件里全然删除,且不能恢复。该表的全部索引也同一时候被删除。

DROP TABLE语句在缺省模式下不减小数据库文件的大小。空间会留给后来的INSERT语句使用。要释放删除产生的空间,能够使用VACUUM命令。若AUTOVACUUM模式开启,则空间会自己主动被DROP TABLE释放。

若使用可选的IF EXISTS子句,在删除的表不存在时就不会报错。

DROP TRIGGER

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

DROP TRIGGER语句删除由CREATE TRIGGER创建的触发器。触发器从数据库的schema中删除。注意当关联的表被撤消时触发器自己主动被删除。

DROP VIEW

sql-command ::= DROP VIEW view-name

DROP VIEW语句删除由CREATE VIEW创建的视图。视图从数据库的schema中删除,表中的数据不会被更改。

EXPLAIN

sql-statement ::= EXPLAIN sql-statement

EXPLAIN命令修饰语是一个非标准的扩展功能,灵感来自PostgreSQL中的同样命令,但操作全然不同。

若EXPLAINkeyword出如今不论什么SQLite的SQL命令之前,则SQLite库返回不加EXPLAIN时运行该命令所须要使用的虚拟机指令序列,而不是真正运行该命令。关于虚拟机指令的很多其它信息參见系统结构描写叙述或关于虚拟机的可用代码

表达式

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 )
like-op ::= LIKE | GLOB | REGEXP

这一节与其他的各节有所不同。我们讨论的不是一个单一的SQL命令,而是作为其他大部分命令的一部分的表达式。

SQLite支持例如以下的二元运算符,按优先级由高至低排列:

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

所支持的一元运算符:

-     +     !     ~

注意等号和“不等”号的两个变种。等号能够是 ===. “不等”号能够是!=<>. ||为“连接符”——它将两个字符串连接起来。 %输出左边部分以右边部分为模取模得到的余数。

二元运算符的结果均为数字,除了||连接符,它给出字符串结果。

文本值(literal value)是一个整数或浮点数。能够使用科学计数法。“.”符号总是被当作小数点即使本地设定中用“,”来表示小数点——用“,”表示小数点会造成歧义。字符串常量由字符串加单引號“‘”构成。字符串内部的单引號可像Pascal中一样用两个单引號来表示。C风格的加反斜线的表示法因为不是标准SQL而不被支持。BLOB文本是以“x”或“X”开头的含有十六进制文本信息的文本值。比如:

X‘53514697465‘

文本值相同能够为“NULL”。

表达式中插入文本值占位符的參数能够使用sqlite3_bind API函数在执行时插入。參数能够是例如以下几种形式:

?NNN   问号尾随数字NNN为第NNN个參数占位。NNN需介于1和999之间。
?   不加数字的问号为下一个參数占位。
:AAAA   冒号带一个标识符名称为一个名为AAAA的參数占位。命名的參数相同能够使用序号占位,被赋予的參数序号为下一个尚未被使用的序号。建议不要混合使用命名代表的參数和序号代表的參数以免引起混淆。
$AAAA   $符号带一个标识符名称也能够为一个名为AAAA的參数占位。在这一情况下标识符名称能够包括一个或很多其它的“::”以及包括不论什么文本的“(...)”后缀。该语法是Tcl编程语言中的一个可变形式。

不使用sqlite3_bind赋值的參数被视为NULL。

LIKE运算符进行模式匹配比較。运算符右边为进行匹配的模式而左边为需进行匹配的字符串。模式中的百分号%匹配结果中的零或随意多个字符。下划线_匹配随意单个字符。其它的随意字符匹配本身或等同的大/小写字符。(即不区分大写和小写的匹配)。(一个bug:SQLite仅对7-bit拉丁字符支持不区分大写和小写匹配。这是因为LIKE运算符对8-bit ISO8859字符或UTF-8字符是大写和小写敏感的。比如,表达式‘a‘ LIKE ‘A‘的值为真而‘æ‘ LIKE ‘Æ‘为假)。

假设使用可选的ESCAPE子句,则尾随ESCAPEkeyword的必须是一个有一个字符的字符串。这一字符(逃逸字符)可用于LIKE模式中,以取代百分号或下划线。逃逸字符后跟百分号,下划线或它本身代表字符串中的百分号,下划线或逃逸字符。插入的LIKE运算符功能通过调用用户函数like(X,Y)来实现。

当使用可选的ESCAPE子句,它对函数给出第三个參数,LIKE的功能能够通过重载SQL函数like()进行改变。

GLOB运算符与LIKE类似,但它使用Unix文件globbing语法作为通配符。另一点不同是GLOB对大写和小写敏感。GLOB和LIKE都能够前缀NOTkeyword构成相反的意思。插入的GLOB运算符功能通过调用用户函数glob(X,Y)能够通过重载函数改变GLOB的功能。

REGEXP运算符是用户函数regexp()的一个特殊的代表符号。缺省情况下regexp()函数不被定义,所以使用REGEXP运算符会报错。当执行时存在用户定义的“regexp”函数的定义,则调用该函数以实现REGEXP运算符功能。

字段名能够是CREATE TABLE语句定义的不论什么名字或例如以下几个特殊标识符之中的一个“ROWID”、“OID”以及“_ROWID_”。这些特殊标识符均代表每一个表每一行关联的那个唯一随机整数键“row key”。只在CREATE TABLE语句没有对这些特殊标识符的真实字段予以定义的情况下,它们才代表“row key”。它们与只读字段相似,能够像不论什么正常字段一样使用,除了在UPDATE或INSERT语句中(即是说你不能加入或更改row key)。“SELECT * ...”不返回row key。

SELECT语句能够在表达式中出现,作为IN运算符的右边运算量,作为一个纯量,或作为EXISTS运算符的运算量。当作纯量或IN的运算量时,SELECT语句的结果仅同意有一个字段,能够使用复合的SELECT(用UNION或 EXCEPT等keyword连接)。作为EXISTS运算符的运算量时,SELECT结果中的字段被忽略,在结果为空时表达式为假,反之为真。若SELECT表达式代表的查询中不含有引用值的部分,则它将在处理其他事务之前被计算,而且结果在必要时会被反复使用。若SELECT表达式含从其他查询中得到的变量,在每一次使用时该表达式均被又一次计算。

当SELECT作为IN运算符的右运算量,在左边的运算量是SELECT产生的随意一个值时,表达式返回TRUE。IN运算符前能够加NOT构成相反的意思。

当SELECT与表达式一同出现且不在IN的右边,则SELECT结果的第一行作为表达式中使用的值。SELECT返回的结果在第一行以后的部分被忽略。返回结果为空时SELECT语句的值为NULL。

CAST表达式将的数据类型改为声明的类型。能够是CREATE TABLE语句字段定义部分定义的对该字段有效的随意非空数据类型。

表达式支持简单函数和聚集函数。简单函数直接从输入获得结果,可用于不论什么表达式中。聚集函数使用结果集中的全部行计算结果,仅用于SELECT语句中。

T以下这些函数是缺省可用的。能够使用C语言写出其他的函数然后使用sqlite3_create_function() API函数加入到数据库引擎中。

abs(X) 返回參数X的绝对值。
coalesce(X,Y,...) 返回第一个非空參数的副本。若全部的參数均为NULL,返回NULL。至少2个參数。
glob(X,Y) 用于实现SQLite的 "X GLOB Y"语法。可使用 sqlite3_create_function() 重载该函数从而改变GLOB运算符的功能。
ifnull(X,Y) 返回第一个非空參数的副本。 若两个參数均为NULL,返回NULL。与上面的 coalesce()相似。
last_insert_rowid() 返回当前数据库连接最后插入行的ROWID。sqlite_last_insert_rowid() API函数相同可用于得到该值。
length(X) 返回X的长度,以字符计。假设SQLite被配置为支持UTF-8,则返回UTF-8字符数而不是字节数。
like(X,Y [,Z]) 用于实现SQL语法"X LIKE Y [ESCAPE Z]".若使用可选的ESCAPE子句,则函数被赋予三个參数,否则仅仅有两个。可使用sqlite3_create_function() 重载该函数从而改变LIKE运算符的功能。
lower(X) 返回X字符串的全部字符小写化版本号。这一转换使用C语言库的tolower()函数,对UTF-8字符不能提供好的支持。
max(X,Y,...) 返回最大值。參数能够不只为数字,能够为字符串。大小顺序由经常使用的排序法则决定。注意,max()在有2个或很多其它參数时为简单函数,但当仅给出一个參数时它变为聚集函数。
min(X,Y,...) 返回最小值。与max()相似。
nullif(X,Y) 当两參数不同一时候返回X,否则返回NULL.
quote(X) 返回參数的适于插入其他SQL语句中的值。字符串会被加入单引號,在内部的引號前会加入逃逸符号。 BLOB被编码为十六进制文本。当前的VACUUM使用这一函数实现。在使用触发器实现撤销/重做功能时这一函数也非常实用。
random(*) 返回介于-2147483648和 +2147483647之间的随机整数。
round(X)
round(X,Y)
X四舍五入,保留小数点后Y位。若忽略Y參数,则默认其为0。
soundex(X) 计算字符串X的soundex编码。參数为NULL时返回字符串“?000”。缺省的SQLite是不支持该函数的,当编译时选项 -DSQLITE_SOUNDEX=1 时该函数才可用。
sqlite_version(*) 返回所执行的SQLite库的版本字符串。如 "2.8.0"。
substr(X,Y,Z) 返回输入字符串X中以第Y个字符開始,Z个字符长的子串。X最左端的字符序号为1。若Y为负,则从右至左数起。若SQLite配置支持UTF-8,则“字符”代表的是UTF-8字符而非字节。
typeof(X) 返回表达式X的类型。返回值可能为“null”、“integer”、“real”、“text”以及“blob”。SQLite的类型处理參见SQLite3的数据类型
upper(X) 返回X字符串的全部字符大写化版本号。这一转换使用C语言库的toupper()函数,对UTF-8字符不能提供好的支持。

下面是缺省可用的聚集函数列表。能够使用C语言写出其他的聚集函数然后使用sqlite3_create_function() API函数加入到数据库引擎中。

在单參数聚集函数中,參数能够加前缀DISTINCT。这时反复參数会被过滤掉,然后才穿入到函数中。比如,函数“count(distinct X)”返回字段X的不反复非空值的个数,而不是字段X的所有非空值。

avg(X) 返回一组中非空的X的平均值。非数字值作0处理。avg()的结果总是一个浮点数,即使全部的输入变量都是整数。

 

count(X)
count(*)
返回一组中X是非空值的次数的第一种形式。另外一种形式(不带參数)返回该组中的行数。
max(X) 返回一组中的最大值。大小由经常使用排序法决定。
min(X) 返回一组中最小的非空值。大小由经常使用排序法决定。仅在全部值为空时返回NULL。
sum(X)
total(X)
返回一组中全部非空值的数字和。若没有非空行,sum()返回NULL而total()返回0.0。NULL通常情况下并非对于“没有行”的和的一个有意义的结果,但SQL标准如此要求,且大部分其他SQL数据库引擎这样定义sum(),所以SQLite 也如此定义以保证兼容。我们提供非标准的total()函数作为解决该SQL语言设计问题的一个简易方法。

total()的返回值式中为浮点数。sum()能够为整数,当全部非空输入均为整数时,和是精确的。若sum()的随意一个输入既非整数也非NULL或计算中产生整数类型的溢出时,sum()返回接近真和的浮点数。

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

INSERT语句有两种基本形式。一种带有“VALUES”keyword,在已有表中插入一个新的行。若不定义字段列表,那么值的数目将与表中的字段数目同样。否则值的数目须与字段列表中的字段数目同样。不在字段列表中的字段被赋予缺省值或NULL(当没有定义缺省值)。

INSERT的另外一种形式从SELECT语句中获取数据。若没有定义字段列表,则从SELECT得到的字段的数目必须与表中的字段数目同样,否则应与定义的字段列表中的字段数目同样。SELECT的每一行结果在表中插入一个新的条目。SELECT能够是简单的或者复合的。假设SELECT语句带有ORDER BY子句,ORDER BY会被忽略。

在使用这一命令时,利用可选的ON CONFLICT子句能够定义替代的约束冲突判定算法。很多其它信息,參见ON CONFLICT。为了兼容MySQL,能够使用REPLACE取代“INSERT OR REPLACE”。

ON CONFLICT子句

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

ON CONFLICT子句不是独立的SQL命令。这是一条能够出如今更多SQL命令中的非标准的子句。因为它并非标准的SQL语言,这里单独介绍它。

ON CONFLICT子句的语法在如上的CREATE TABLE命令中示出。对于INSERT和UPDATE,关键词“ON CONFLICT”由“OR”替代,这样语法显得自然。比如,不用写“INSERT ON CONFLICT IGNORE”而是“INSERT OR IGNORE”。二者表示同样的意思。

ON CONFLICT子句定义了解决约束冲突的算法。有五个选择:ROLLBACK、ABORT、FAIL、IGNORE和REPLACE,缺省方案是ABORT。选项含义例如以下:

ROLLBACK

当发生约束冲突,马上ROLLBACK,即结束当前事务处理,命令中止并返回SQLITE_CONSTRAINT代码。若当前无活动事务(除了每一条命令创建的默认事务以外),则该算法与ABORT同样。

ABORT

当发生约束冲突,命令收回已经引起的改变并中止返回SQLITE_CONSTRAINT。但因为不运行ROLLBACK,所曾经面的命令产生的改变将予以保留。缺省採用这一行为。

FAIL

当发生约束冲突,命令中止返回SQLITE_CONSTRAINT。但遇到冲突之前的全部改变将被保留。比如,若一条UPDATE语句在100行遇到冲突100th,前99行的改变将被保留,而对100行或以后的改变将不会发生。

IGNORE

当发生约束冲突,发生冲突的行将不会被插入或改变。但命令将照常运行。在冲突行之前或之后的行将被正常的插入和改变,且不返回错误信息。

REPLACE

当发生UNIQUE约束冲突,先存在的,导致冲突的行在更改或插入发生冲突的行之前被删除。这样,更改和插入总是被运行。命令照常运行且不返回错误信息。当发生NOT NULL约束冲突,导致冲突的NULL值会被字段缺省值代替。若字段无缺省值,运行ABORT算法。

当冲突应对策略为满足约束而删除行时,它不会调用删除触发器。但在新版中这一特性可能被改变。

INSERT或UPDATE的OR子句定义的算法会覆盖CREATE TABLE所定义的。ABORT算法将在未定义不论什么算法时缺省使用。

SQLite支持的编译指令(Pragma)

PRAGMA命令是用于改动SQlite库或查询SQLite库内部数据(non-table)的特殊命令。PRAGMA 命令使用与其他SQLite命令(比如:SELECT、INSERT)同样的接口,但在例如以下重要方面与其他命令不同:

  • 在未来的SQLite版本号中部分Pragma可能被删除或加入,要小心使用。
  • 当使用未知的Pragma语句时不产生报错。未知的Pragma只会被忽略,即是说若是打错了Pragma语句SQLite不会提示用户。
  • 一些Pragma在SQL编译阶段生效而非运行阶段。即是说若使用C语言的sqlite3_compile()、sqlite3_step()、sqlite3_finalize() API(或相似的封装接口中),Pragma可能在调用sqlite3_compile()期间起作用。
  • Pragma命令不与其他SQL引擎兼容。

可用的pragma命令有例如以下四个基本类型:


PRAGMA命令语法

sql-statement ::= PRAGMA name [= value] |
PRAGMA
function(arg)

使用整数值value的pragma也能够使用符号表示,字符串“on”、“true”和“yes”等同于1,“off”、“false”和“no”等同于0。这些字符串大写和小写不敏感且无须进行引用。无法识别的字符串被当作1且不会报错。value返回时是整数。


用于改动SQLite库的操作的Pragma

  • PRAGMA auto_vacuum;
    PRAGMA auto_vacuum =
    0 | 1;

    查询或设置数据库的auto-vacuum标记。

    正常情况下,当提交一个从数据库中删除数据的事务时,数据库文件不改变大小。未使用的文件页被标记并在以后的加入操作中再次使用。这样的情况下使用VACUUM命令释放删除得到的空间。

    当开启auto-vacuum,当提交一个从数据库中删除数据的事务时,数据库文件自己主动收缩,(VACUUM命令在auto-vacuum开启的数据库中不起作用)。数据库会在内部存储一些信息以便支持这一功能,这使得数据库文件比不开启该选项时略微大一些。

    仅仅有在数据库中未建不论什么表时才干改变auto-vacuum标记。试图在已有表的情况下改动不会导致报错。

  • PRAGMA cache_size;
    PRAGMA cache_size =
    Number-of-pages;

    查询或改动SQLite一次存储在内存中的数据库文件页数。每页使用约1.5K内存,缺省的缓存大小是2000。若须要使用改变大量多行的UPDATE或DELETE命令,而且不介意SQLite使用很多其它的内存的话,能够增大缓存以提高性能。

    当使用cache_size pragma改变缓存大小时,改变仅对当前对话有效,当数据库关闭又一次打开时缓存大小恢复到缺省大小。要想永久改变缓存大小,使用default_cache_size pragma。

  • PRAGMA case_sensitive_like;
    PRAGMA case_sensitive_like =
    0 | 1;

    LIKE运算符的缺省行为是忽略latin1字符的大写和小写。因此在缺省情况下‘a‘ LIKE ‘A‘的值为真。能够通过打开case_sensitive_like pragma来改变这一缺省行为。当启用case_sensitive_like,‘a‘ LIKE ‘A‘为假而 ‘a‘ LIKE ‘a‘依旧为真。

  • PRAGMA count_changes;
    PRAGMA count_changes =
    0 | 1;

    查询或更改count-changes标记。正常情况下INSERT, UPDATE和DELETE语句不返回数据。当开启count-changes,以上语句返回一行含一个整数值的数据——该语句插入、改动或删除的行数。返回的行数不包含由触发器产生的插入、改动或删除等改变的行数。

  • PRAGMA default_cache_size;
    PRAGMA default_cache_size =
    Number-of-pages;

    查询或改动SQLite一次存储在内存中的数据库文件页数。每页使用约1.5K内存,它与cache_size pragma相似,仅仅是它永久性地改变缓存大小。利用该pragma,你能够设定一次缓存大小,而且每次又一次打开数据库时都继续使用该值。

  • PRAGMA default_synchronous;

    该语句在2.8版本号中可用,但在3.0版中被去掉了。这条pragma非常危急且不推荐使用,安全起见在该文档中不涉及此pragma的使用方法。

  • PRAGMA empty_result_callbacks;
    PRAGMA empty_result_callbacks =
    0 | 1;

    查询或更改empty-result-callbacks标记。

    empty-result-callbacks标记只影响sqlite3_exec API函数。正常情况下,empty-result-callbacks标记清空,则对返回0行数据的命令不调用sqlite3_exec()的回叫函数,当设置了empty-result-callbacks,则调用回叫 函数一次,置第三个參数为0(NULL)。这使得使用sqlite3_exec() API的程序即使在一条查询不返回数据时依旧检索字段名。

  • PRAGMA encoding;
    PRAGMA encoding = "UTF-8";
    PRAGMA encoding = "UTF-16";
    PRAGMA encoding = "UTF-16le";
    PRAGMA encoding = "UTF-16be";

    在第一种形式中,若主数据库已创建,这条pragma返回主数据库使用得文本编码格式,为“UTF-8”、“UTF-16le”(little-endian UTF-16 encoding)或者“UTF-16be”(big-endian UTF-16 encoding)中的一种。 若主数据库未创建,返回值为当前会话创建的主数据库将要使用的文本编码格式。

    另外一种及以后几种形式仅仅在主数据库未创建时有效。这时该pragma设置当前会话创建的主数据库将要使用的文本编码格式。“UTF-16”表示“使用本机字节顺序的UTF-16编码”。若这些形式在主数据库创建后使用,将被忽略且不产生不论什么效果。

    数据库的编码格式设置后不可以被改变。

    ATTACH命令创建的数据库使用与主数据库同样的编码格式。

  • PRAGMA full_column_names;
    PRAGMA full_column_names =
    0 | 1;

    查询或更改the full-column-names标记。该标记影响SQLite命名SELECT语句(当字段表达式为表-字段或通配符"*"时)返回的字段名的方式。正常情况下,当SELECT语句将两个或多个表连接时,这类结果字段的返回名为,当SELECT语句查询一个单独的表时,返回字段名为。当设置了full-column-names标记,返回的字段名将统一为 无论是否对表进行了连接。

    若short-column-names和full-column-names标记同一时候被设置,则使用full-column-names方式。

  • PRAGMA fullfsync
    PRAGMA fullfsync =
    0 | 1;

    查询或更改fullfsync标记。该标记决定是否在支持的系统上使用F_FULLFSYNC同步模式。缺省值为off。截至眼下(2006-02-10)仅仅有Mac OS X系统支持F_FULLFSYNC。

  • PRAGMA page_size;
    PRAGMA page_size =
    bytes;

    查询或设置page-size值。仅仅有在未创建数据库时才干设置page-size。页面大小必须是2的整数倍且大于等于512小于等于8192。上限能够通过在编译时改动宏定义SQLITE_MAX_PAGE_SIZE的值来改变。上限的上限是32768。

  • PRAGMA read_uncommitted;
    PRAGMA read_uncommitted =
    0 | 1;

    查询,设置或清除READ UNCOMMITTED isolation(读取未授权的分隔符)。缺省的SQLite分隔符等级是SERIALIZABLE。不论什么线程或进程可选用READ UNCOMMITTED isolation,但除了共享公共页和schema缓存的连接之间以外的地方也会使用SERIALIZABLE。缓存共享通过sqlite3_enable_shared_cache() API开启,且仅仅在执行同一线程的连接间有效。缺省情况下缓存共享是关闭的。

  • PRAGMA short_column_names;
    PRAGMA short_column_names =
    0 | 1;

    查询或更改the short-column-names标记。该标记影响SQLite命名SELECT语句(当字段表达式为表-字段或通配符"*"时)返回的字段名的方式。正常情况下,当SELECT语句将两个或多个表连接时,这类结果字段的返回名为,当SELECT语句查询一个单独的表时,返回字段名为。当设置了full-column-names标记,返回的字段名将统一为无论是否对表进行了连接。

    若short-column-names和full-column-names标记同一时候被设置,则使用full-column-names方式。

  • PRAGMA synchronous;
    PRAGMA synchronous = FULL;
    (2)
    PRAGMA synchronous = NORMAL;
    (1)
    PRAGMA synchronous = OFF;
    (0)

    查询或更改“synchronous”标记的设定。第一种形式(查询)返回整数值。 当synchronous设置为FULL(2),SQLite数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘。这使系统崩溃或电源出问题时能确保数据库在重起后不会损坏。FULL synchronous非常安全但非常慢。当synchronous设置为NORMAL,SQLite数据库引擎在大部分紧急时刻会暂停,但不像FULL模式下那么频繁。NORMAL模式下有非常小的几率(但不是不存在)发生电源故障导致数据库损坏的情况。但实际上,在这样的情况下非常可能你的硬盘已经不能使用,或者发生了其它的不可恢复的硬件错误。设置为synchronous OFF(0)时,SQLite在传递数据给系统以后直接继续而不暂停。若执行SQLite的应用程序崩溃,数据不会损伤,但在系统崩溃或写入数据时意外断电的情况下数据库可能会损坏。还有一方面,在synchronous OFF时一些操作可能会快50倍甚至很多其它。

    在SQLite2中,缺省值为NORMAL,而在3中改动为FULL。

  • PRAGMA temp_store;
    PRAGMA temp_store = DEFAULT;
    (0)
    PRAGMA temp_store = FILE;
    (1)
    PRAGMA temp_store = MEMORY;
    (2)

    查询或更改“temp_store”參数的设置。当temp_store设置为DEFAULT(0),使用编译时的C预处理宏TEMP_STORE来定义储存暂时表和暂时索引的位置。当设置为MEMORY(2)暂时表和索引存放于内存中。当设置为FILE(1)则存放于文件里。temp_store_directory pragma可用于指定存放该文件的文件夹。当改变temp_store设置,全部已存在的暂时表、索引、触发器及视图将被马上删除。

    库中的编译时C预处理标志TEMP_STORE能够覆盖该pragma设置。以下的表给出TEMP_STORE预处理宏和temp_store pragma交互作用的总结:

    TEMP_STORE PRAGMA
    temp_store
    暂时表和索引
    使用的存储方式
    0 any 文件
    1 0 文件
    1 1 文件
    1 2 内存
    2 0 内存
    2 1 文件
    2 2 内存
    3 any 内存

  • PRAGMA temp_store_directory;
    PRAGMA temp_store_directory = ‘directory-name‘;

    查询或更改“temp_store_directory”设置——存储暂时表和索引的文件所在的文件夹。仅在当前连接有效,在建立新连接时重置为缺省值。

    当改变了temp_store_directory设置,全部已有的暂时表、索引、触发器、视图会被直接删除。建议在数据库一打开时就设置好temp_store_directory。

    directory-name需用单引號引起来。要想恢复缺省文件夹,把directory-name设为空字符串。比如 PRAGMA temp_store_directory = ‘‘。若directory-name未找到或不可写会引发错误。

    暂时文件的缺省文件夹与主机的系统有关,使用Unix/Linux/OSX系统的主机,缺省文件夹是例如以下序列之中第一个可写的/var/tmp、/usr/tmp、/tmp、current-directory。对于Windows NT,缺省文件夹由Windows决定,一般为C:/Documents and Settings/user-name/Local Settings/Temp/。SQLite创建的暂时文件在使用完成时就被unlink,所以操作系统能够在SQLite进程进行中自己主动删除暂时文件。于是,正常情况下不能通过lsdir命令看到暂时文件。


用于查询数据库的schema的Pragma

  • PRAGMA database_list;

    对每一个打开的数据库,使用该数据库的信息调用一次回叫函数。使用包含附加的数据库名和索引名在内的參数。第一行用于主数据库,第二行用于存放暂时表的暂时数据库。

  • PRAGMA foreign_key_list(table-name);

    对于參数表中每一个涉及到字段的外键,使用该外键的信息调用一次回叫函数。每一个外键中的每一个字段都将调用一次回叫函数。

  • PRAGMA index_info(index-name);

    对该索引涉及到的每一个字段,使用字段信息(字段名、字段号)调用一次回叫函数。

  • PRAGMA index_list(table-name);

    对表中的每一个索引,使用索引信息调用回叫函数。參数包含索引名和一个指示索引是否唯一的标志。

  • PRAGMA table_info(table-name);

    对于表中的每一个字段,使用字段信息(字段名、数据类型、可否为空、缺省值)调用回叫函数。


用于查询/更改版本号信息的Pragma

  • PRAGMA [database.]schema_version;
    PRAGMA [database.]schema_version =
    integer ;
    PRAGMA [database.]user_version;
    PRAGMA [database.]user_version =
    integer ;

    这两条pragma分别用于设置schema-version和user-version的值。schema-version和user-version均为32位有符号整数,存放于数据库头中。

    schema-version通常仅仅由SQLite内部操作。每当数据库的Schema改变时(创建或撤消表或索引),SQLite将这个值增大。Schema版本号在每一次Query被运行时被SQLite所使用,以确定编译SQL Query时内部Cache的Schema与编译后的Query实际运行时数据库的Schema相匹配。使用“PRAGMA schema_version”更改schema-version会破坏这一机制,有导致程序崩溃或数据库损坏的潜在危急。请小心使用!

    user-version不在SQLite内部使用,不论什么程序能够用它来做不论什么事。


用于库Debug的Pragma

  • PRAGMA integrity_check;

    该命令对整个数据库进行完整性检查,查找次序颠倒的记录,丢失的页,残缺的记录以及损坏的索引。若发现不论什么问题则返回一形容问题所在的字符串,若一切正常返回“ok”。

  • PRAGMA parser_trace = ON; (1)
    PRAGMA parser_trace = OFF;
    (0)

    打开或关闭SQLite库中的SQL语法分析追踪,用于Debug。仅仅有当SQLite不使用NDEBUG宏进行编译时该pragma才可用。

  • PRAGMA vdbe_trace = ON; (1)
    PRAGMA vdbe_trace = OFF;
    (0)

    打开或关闭SQLite库中的虚拟数据库引擎追踪,用于Debug。很多其它信息,查看 VDBE文档

  • PRAGMA vdbe_listing = ON; (1)
    PRAGMA vdbe_listing = OFF;
    (0)

    打开或关闭虚拟机程序列表,当开启列表功能,整个程序的内容在运行前被打印出来,就像在每条语句之前自己主动运行EXPLAIN。语句在打印列表之后正常运行。用于Debug。很多其它信息,查看VDBE文档

REINDEX

sql-statement ::= REINDEX collation name
sql-statement ::= REINDEX [database-name .] table/index-name

REINDEX命令用于删除并从草稿重建索引。当比較顺序改变时该命令显得非常有效。

在第一种形式中,全部附加数据库中使用该比較顺序的索引均被重建。在另外一种形式中,[database-name.]table/index-name标识出一个表,全部关联该表的索引被重建。若标识出索引,则只该索引被删除并重建。

若不指定database-name而指定表/索引名以及比較顺序,仅仅有关联该比較顺序的索引被重建。在重建索引时总是指定database-name能够消除这一歧义。

REPLACE

sql-statement ::= REPLACE INTO [database-name .] table-name [( column-list )] VALUES ( value-list ) |
REPLACE INTO
[database-name .] table-name [( column-list )] select-statement

REPLACE命令用于替代INSERT的“INSERT OR REPLACE”变体,以更好的兼容MySQL。查看INSERT命令文档获取很多其它信息。

SELECT

sql-statement ::= SELECT [ALL | DISTINCT] result [FROM table-list]
[WHERE expr]
[GROUP BY expr-list]
[HAVING expr]
[compound-op select]*
[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 )]
sort-expr-list ::= expr [sort-order] [, expr [sort-order]]*
sort-order ::= [ COLLATE collation-name ] [ ASC | DESC ]
compound_op ::= UNION | UNION ALL | INTERSECT | EXCEPT

SELECT语句用于查询数据库。一条SELECT命令的返回结果是零或多行每行有固定字段数的数据。字段的数目由在SELECT和FROM之间的表达式列表定义。随意的表达式都能够被用作结果。若表达式是 *则表示全部表的全部字段。若表达式是表的名字后接.*则结果为该表中的全部字段。

DISTINCTkeyword的使用会使返回的结果是原结果的一个不含同样行的子集。NULL值被觉得是同样的。缺省行为是返回全部的行,为清楚起见能够使用keywordALL。

查询对FROM之后定义的一个或多个表进行。若多个表用逗号连接,则查询针对它们的交叉连接。全部的SQL-92连接语法均能够用于定义连接。圆括号里的副查询可能被FROM子句中的随意表名替代。当结果中仅有一行包括表达式列表中的结果的行时,整个的FROM子句会被忽略。

WHERE子句能够限定查询操作的行数目。

GROUP BY子句将一行或多行结果合成单行输出。当结果有聚集函数时这将尤事实上用。GROUP BY子句的表达式不须是出如今结果中的表达式。HAVING子句与WHERE类似,仅仅是HAVING用于过滤分组创建的行。HAVING子句可能包括值,甚至是不出如今结果中的聚集函数。

ORDER BY子句对所得结果依据表达式排序。表达式无须是简单SELECT的结果,但在复合SELECT中每一个表达式必须精确相应一个结果字段。每一个表达式可能尾随一个可选的COLLATEkeyword以及用于排序文本的比較函数名称和/或keywordASC或DESC,用于说明排序规则。

LIMIT子句限定行数的最大值。负的LIMIT表示无上限。后跟可选的OFFSET说明跳过结果集中的前多少行。在一个复合查询中,LIMIT子句只同意出如今终于SELECT语句中。限定对于全部的查询均适用,而不不过加入了LIMIT子句的那一行。注意OFFSETkeyword用于LIMIT子句中,则限制值是第一个数字,而偏移量(offset)是第二个数字。若用逗号替代OFFSETkeyword,则偏移量是第一个数字而限制值是第二个数字。这是为了加强对遗留的SQL数据库的兼容而有意造成的矛盾。

复合的SELECT由两个或很多其它简单SELECT经由UNION、UNION ALL、INTERSECT、EXCEPT中的一个运算符连接而成。在一个复合SELECT中,各个SELECT需指定同样个数的结果字段。仅同意一个ORDER BY子句出如今SELECT的末尾。UNION和UNION ALL运算符从左至右将全部SELECT的结果合成一个大的表。二者的差别在于UNION的全部结果行是不同样的而UNION ALL同意反复行。INTERSECT运算符取左右两个SELECT结果的交。EXCEPT从左边SELECT的结果中除掉右边SELECT的结果。三个或很多其它SELECT复合时,它们从左至右结合。

UPDATE

sql-statement ::= UPDATE [ OR conflict-algorithm ] [database-name .] table-name
SET
assignment [, assignment]*
[WHERE expr]
assignment ::= column-name = expr

UPDATE语句用于改变表中所选行的字段值。每一个UPDATE的赋值的等号左边为字段名而右边为随意表达式。表达式能够使用其他字段的值。全部的表达式将在赋值之前求出结果。能够使用WHERE子句限定须要改变的行。

在使用这一命令时,利用可选的ON CONFLICT子句能够定义替代的约束冲突判定算法。很多其它信息,參见ON CONFLICT

VACUUM

sql-statement ::= VACUUM [index-or-table-name]

VACUUM命令是SQLite的一个扩展功能,模仿PostgreSQL中的同样命令而来。若调用VACUUM带一个表名或索引名,则将整理该表或索引。在SQLite 1.0中,VACUUM命令调用gdbm_reorganize()整理后端数据库文件。

SQLITE 2.0.0中去掉了GDBM后端,VACUUM无效。在2.8.1版中,VACUUM被又一次实现。如今索引名或表名被忽略。

当数据库中的一个对象(表、索引或触发器)被撤销,会留下空白的空间。它使数据库比须要的大小更大,但能加快插入速度。实时的插入和删除会使得数据库文件结构混乱,减慢对数据库内容訪问的速度。VACUUM命令复制主数据库文件到暂时数据库并从暂时数据库又一次加载主数据库,以整理数据库文件。这将除去空白页,使表数据彼此相邻排列,并整理数据库文件结构。不能对附加数据库文件进行以上操作。

若当前有活动事务,该命令无法起作用。对于In-Memory数据库,该命令无效。

SQLite 3.1中,能够通过使用auto-vacuum模式代替VACUUM命令,使用auto_vacuum pragma开启该模式。

SQLite的SQL语法

上一篇:IsDbNull 方法的用法


下一篇:Sql Server 添加外部程序集基本操作