原文地址:http://blog.csdn.net/ejzhang/article/details/6224915
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,即結束當前事務處理,命令中止並返回SQLITE_CONSTRAINT代碼。若當前無活動事務(除了每一條命令創建的默認事務以外),則該算法與ABORT相同。
當發生約束衝突,命令收回已經引起的改變並中止返回SQLITE_CONSTRAINT。但由於不執行ROLLBACK,所以前面的命令產生的改變將予以保留。缺省採用這一行爲。
當發生約束衝突,命令中止返回SQLITE_CONSTRAINT。但遇到衝突之前的所有改變將被保留。例如,若一條UPDATE語句在100行遇到衝突100th,前99行的改變將被保留,而對100行或以後的改變將不會發生。
當發生約束衝突,發生衝突的行將不會被插入或改變。但命令將照常執行。在衝突行之前或之後的行將被正常的插入和改變,且不返回錯誤信息。
當發生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 臨時表和索引
使用的存儲方式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進程進行中自動刪除臨時文件。於是,正常情況下不能通過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 開啓該模式。