SQLite庫可以解析大部分标準SQL語言。但它也省去了一些特性并且加入了一些自己的新特性。這篇文檔就是試圖描述那些SQLite支援/不支援的SQL文法的。檢視關鍵字清單。
如下文法表格中,純文字用藍色粗體顯示。非終極符号為斜體紅色。作為文法一部分的運算符用黑色Roman字型表示。
這篇文檔隻是對SQLite實作的SQL文法的綜述,有所忽略。想要得到更詳細的資訊,參考源代碼和文法檔案“parse.y”。
SQLite執行如下的文法:
- ALTER TABLE
- ANALYZE
- ATTACH DATABASE
- BEGIN TRANSACTION
- 注釋
- COMMIT TRANSACTION
- COPY
- CREATE INDEX
- CREATE TABLE
- CREATE TRIGGER
- CREATE VIEW
- DELETE
- DETACH DATABASE
- DROP INDEX
- DROP TABLE
- DROP TRIGGER
- DROP VIEW
- END TRANSACTION
- EXPLAIN
- 表達式
- INSERT
- ON CONFLICT子句
- PRAGMA
- REINDEX
- REPLACE
- ROLLBACK TRANSACTION
- SELECT
- UPDATE
- VACUUM
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-name到new-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”關鍵字後跟新索引的名字,關鍵字“ON”,待索引表的名字,以及括弧内的用于索引鍵的字段清單構成。每個字段名可以跟随“ASC”或“DESC”關鍵字說明排序法則,但在目前版本中排序法則被忽略。排序總是按照上升序。
每個字段名後跟COLLATE子句定義文本記錄的比較順序。預設的比較順序是由CREATE TABLE語句說明的比較順序。若不定義比較順序,則使用内建的二進制比較順序。
附加到單個表上的索引數目沒有限制,索引中的字段數也沒有限制。
若UNIQUE關鍵字出現在CREATE和INDEX之間,則不允許重名的索引記錄。試圖插入重名記錄将會導緻錯誤。
每條CREATE INDEX語句的文本儲存于sqlite_master或sqlite_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”關鍵字後跟一個新的表名以及括号内的一堆定義和限制。表名可以是字元串或者辨別符。以“sqlite_”開頭的表名是留給資料庫引擎使用的。
每個字段的定義是字段名後跟字段的資料類型,接着是一個或多個的字段限制。字段的資料類型并不限制字段中可以存放的資料。可以檢視SQLite3的資料類型擷取更多資訊。UNIQUE限制為指定的字段建立索引,該索引須含有唯一鍵。COLLATE子句說明在比較字段的 文字記錄時所使用的排序函數。預設使用内嵌的BINARY排序函數。
DEFAULT限制說明在使用INSERT插入字段時所使用的預設值。該值可以是NULL,字元串常量或一個數。從3.1.0版開始,預設值也可以是以下特殊的與事件無關的關鍵字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索引。然而,若主鍵定義在單一的INTEGER類型的字段上,則該字段在内部被用作表的B-Tree鍵。這即是說字段僅能容納唯一整數值。(在除此之外的其它情況下,SQLite忽略資料類型的說明 ,允許任何類型的資料放入字段中,不管該字段被聲明為什麼資料類型。)若一個表中不含一個INTEGER PRIMARY KEY字段,則B-Tree鍵為自動産生的整數。一行的B-Tree鍵可以通過如下特殊的名字“ROWID”、“OID”或“_ROWID_”進行通路,不論是否有INTEGER PRIMARY KEY存在。INTEGER PRIMARY KEY字段可以使用關鍵字AUTOINCREMENT聲明。AUTOINCREMENT關鍵字修改了B-Tree鍵自動産生的方式。B-Tree鍵的生成的其它資訊可以在這裡找到。
若“TEMP”或“TEMPORARY”關鍵字出現在“CREATE”和“TABLE”之間,則所建立的表僅在目前資料庫連接配接可見,并在斷開連接配接時自動被删除。在臨時表上建立的任何索引也是臨時的。臨時表和索引單獨存儲在與主資料庫檔案不同的檔案中。
若說明了,則表在該資料庫中被建立。同時聲明和TEMP關鍵字會出錯,除非 是“temp”。若不聲明資料庫名,也不使用TEMP關鍵字,則表建立于主資料庫中。
在每個限制後跟可選的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”關鍵字出現在“CREATE”和“VIEW”之間,則建立的視圖僅對打開資料庫的程序可見,且在資料庫關閉時自動删除。
若指定了則視圖在指定的資料庫中建立。同時使用和TEMP關鍵字會導緻錯誤,除非是“temp”。若不聲明資料庫名,也不使用TEMP關鍵字,則視圖建立于主資料庫中。
你不能對視圖使用COPY、DELETE、INSERT或UPDATE,視圖在SQLite中是隻讀的。多數情況下你可以在視圖上建立TRIGGER來達到相同目的。用DROP VIEW指令來删除視圖。
DELETE
sql-statement ::= | DELETE FROM [database-name .] table-name [WHERE expr] |
DELETE指令用于從表中删除記錄。指令包含“DELETE FROM”關鍵字以及需要删除的記錄所在的表名。
若不使用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中的相同指令,但操作完全不同。
若EXPLAIN關鍵字出現在任何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子句,則跟随ESCAPE關鍵字的必須是一個有一個字元的字元串。這一字元(逃逸字元)可用于LIKE模式中,以代替百分号或下劃線。逃逸字元後跟百分号,下劃線或它本身代表字元串中的百分号,下劃線或逃逸字元。插入的LIKE運算符功能通過調用使用者函數like(X,Y)來實作。
當使用可選的ESCAPE子句,它對函數給出第三個參數,LIKE的功能可以通過重載SQL函數like()進行改變。
GLOB運算符與LIKE相似,但它使用Unix檔案globbing文法作為通配符。還有一點不同是GLOB對大小寫敏感。GLOB和LIKE都可以字首NOT關鍵字構成相反的意思。插入的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等關鍵字連接配接)。作為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”關鍵字,在已有表中插入一個新的行。若不定義字段清單,那麼值的數目将與表中的字段數目相同。否則值的數目須與字段清單中的字段數目相同。不在字段清單中的字段被賦予預設值或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指令有如下四個基本類型:
- 用于察看目前資料庫的模式。
- 用于修改SQLite庫的操作或查詢目前的操作模式。
- 用于查詢或修改兩個資料庫的版本号,schema-version和user-version.
- 用于調試庫和校驗資料庫檔案。
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
臨時表和索引
使用的存儲方式
any 檔案 1 檔案 1 1 檔案 1 2 記憶體 2 記憶體 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程序進行中自動删除臨時檔案。于是,正常情況下不能通過ls或dir指令看到臨時檔案。
用于查詢資料庫的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之間的表達式清單定義。任意的表達式都可以被用作結果。若表達式是 *則表示所有表的所有字段。若表達式是表的名字後接.*則結果為該表中的所有字段。
DISTINCT關鍵字的使用會使傳回的結果是原結果的一個不含相同行的子集。NULL值被認為是相同的。預設行為是傳回所有的行,為清楚起見可以使用關鍵字ALL。
查詢對FROM之後定義的一個或多個表進行。若多個表用逗号連接配接,則查詢針對它們的交叉連接配接。所有的SQL-92連接配接文法均可以用于定義連接配接。圓括号中的副查詢可能被FROM子句中的任意表名替代。當結果中僅有一行包含表達式清單中的結果的行時,整個的FROM子句會被忽略。
WHERE子句可以限定查詢操作的行數目。
GROUP BY子句将一行或多行結果合成單行輸出。當結果有聚集函數時這将尤其有用。GROUP BY子句的表達式不須是出現在結果中的表達式。HAVING子句與WHERE相似,隻是HAVING用于過濾分組建立的行。HAVING子句可能包含值,甚至是不出現在結果中的聚集函數。
ORDER BY子句對所得結果根據表達式排序。表達式無須是簡單SELECT的結果,但在複合SELECT中每個表達式必須精确對應一個結果字段。每個表達式可能跟随一個可選的COLLATE關鍵字以及用于排序文本的比較函數名稱和/或關鍵字ASC或DESC,用于說明排序規則。
LIMIT子句限定行數的最大值。負的LIMIT表示無上限。後跟可選的OFFSET說明跳過結果集中的前多少行。在一個複合查詢中,LIMIT子句隻允許出現在最終SELECT語句中。限定對于所有的查詢均适用,而不僅僅是添加了LIMIT子句的那一行。注意OFFSET關鍵字用于LIMIT子句中,則限制值是第一個數字,而偏移量(offset)是第二個數字。若用逗号替代OFFSET關鍵字,則偏移量是第一個數字而限制值是第二個數字。這是為了加強對遺留的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開啟該模式。