該文章徹底摘自轉自:北大青鳥[Android新手區] SQLite 操做詳解--SQL語法 :http://home.bdqn.cn/thread-49363-1-1.htmlphp
SQLite庫能夠解析大部分標準SQL語言。但它也省去了一些特性而且加入了一些本身的新特性。這篇文檔就是試圖描述那些SQLite支持/不支持的SQL語法的。查看關鍵字列表。html 以下語法表格中,純文本用藍色粗體顯示。非終極符號爲斜體紅色。做爲語法一部分的運算符用黑色Roman字體表示。算法 這篇文檔只是對SQLite實現的SQL語法的綜述,有所忽略。想要獲得更詳細的信息,參考源代碼和語法文件「parse.y」。sql SQLite執行以下的語法:數據庫
ALTER TABLE
SQLite版本的的ALTER TABLE命令容許用戶重命名或添加新的字段到已有表中,不能從表中刪除字段。express RENAME TO語法用於重命名錶名[database-name.]table-name到new-table-name。這一命令不能用於在附加數據庫之間移動表,只能在同一個數據庫中對錶進行重命名。編程 若須要重命名的表有觸發器或索引,在重命名後它們依然屬於該表。但若定義了視圖,或觸發器執行的語句中有提到 表的名字,則它們不會被自動改成使用新的表名。若要進行這一類的修改,則需手工撤銷並使用新的表名重建觸發器或視圖。後端 ADD [COLUMN]語法用於在已有表中添加新的字段。新字段老是添加到已有字段列表的末尾。Column-def能夠是CREATE TABLE中容許出現的任何形式,且須符合以下限制:緩存
ALTER TABLE語句的執行時間與表中的數據量無關,它在操做一個有一千萬行的表時的運行時間與操做僅有一行的表時是同樣的。安全 在對數據庫運行ADD COLUMN以後,該數據庫將沒法由SQLite 3.1.3及更早版本讀取,除非運行VACUUM命令。 ANALYZE
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
從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
從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能夠在當前讀取的線程讀取結束後再次試圖讀取數據庫。 註釋
註釋不是SQL命令,但會出如今SQL查詢中。它們被解釋器處理爲空白部分。它們能夠在任何空白可能存在的地方開始 ,即便是在跨越多行的表達式中。 SQL風格的註釋僅對當前行有效。 C風格的註釋能夠跨越多行。若沒有結束符號,註釋的範圍將一直延伸到輸入末尾,且不會引發報錯。新的SQL語句能夠從多行註釋結束的地方開始。C風格註釋能夠嵌入任何空白能夠出現的地方,包括表達式內,或其餘SQL語句中間, 而且C風格的註釋不互相嵌套。SQL風格的註釋出如今C風格註釋中時將被忽略。 COPY
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
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
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
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處可用,例如:
當使用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()可用於觸發器程序,使用以下語法:
當觸發器程序執行中調用了上述前三個之一的形式時,則執行指定的ON CONFLICT進程(ABORT、FAIL或者ROLLBACK)且終止當前查詢,返回一個SQLITE_CONSTRAINT錯誤並說明錯誤信息。 當調用RAISE(IGNORE),當前觸發器程序的餘下部分,觸發該觸發器的語句和任何以後的觸發器程序被忽略而且不恢復對數據庫的已有改變。若觸發觸發器的語句是一個觸發器程序自己的一部分,則原觸發器程序從下一步起繼續執行。 使用DROP TRIGGER刪除觸發器。 CREATE VIEW
CREATE VIEW命令爲一個包裝好的SELECT語句命名。當建立了一個視圖,它能夠用於其餘SELECT的FROM字句中代替表名。 若「TEMP」或「TEMPORARY」關鍵字出如今「CREATE」和「VIEW」之間,則建立的視圖僅對打開數據庫的進程可見,且在數據庫關閉時自動刪除。 若指定了則視圖在指定的數據庫中建立。同時使用和TEMP關鍵字會致使錯誤,除非是「temp」。若不聲明數據庫名,也不使用TEMP關鍵字,則視圖建立於主數據庫中。 你不能對視圖使用COPY、DELETE、INSERT或UPDATE,視圖在SQLite中是隻讀的。多數狀況下你能夠在視圖上建立TRIGGER來達到相同目的。用DROP VIEW命令來刪除視圖。 DELETE
DELETE命令用於從表中刪除記錄。命令包含「DELETE FROM」關鍵字以及須要刪除的記錄所在的表名。 若不使用WHERE子句,表中的全部行將所有被刪除。不然僅刪除符合條件的行。 DETACH DATABASE
該語句拆分一個以前使用ATTACH DATABASE語句附加的數據庫鏈接。可使用不一樣的名字屢次附加同一數據庫,而且拆分一個鏈接不會影響其餘鏈接。 若SQLite在事務進行中,該語句不起做用。 DROP INDEX
DROP INDEX語句刪除由CREATE INDEX語句建立的索引。索引將從數據庫結構和磁盤文件中徹底刪除,惟一的恢復方法是從新輸入相應的CREATE INDEX命令。 DROP TABLE語句在缺省模式下不減少數據庫文件的大小。空間會留給後來的INSERT語句使用。要釋放刪除產生的空間,可使用VACUUM命令。若AUTOVACUUM模式開啓,則空間會自動被DROP INDEX釋放。 DROP TABLE
DROP TABLE語句刪除由CREATE TABLE語句建立的表。表將從數據庫結構和磁盤文件中徹底刪除,且不能恢復。該表的全部索引也同時被刪除。 DROP TABLE語句在缺省模式下不減少數據庫文件的大小。空間會留給後來的INSERT語句使用。要釋放刪除產生的空間,可使用VACUUM命令。若AUTOVACUUM模式開啓,則空間會自動被DROP TABLE釋放。 若使用可選的IF EXISTS子句,在刪除的表不存在時就不會報錯。 DROP TRIGGER
DROP TRIGGER語句刪除由CREATE TRIGGER建立的觸發器。觸發器從數據庫的schema中刪除。注意當關聯的表被撤消時觸發器自動被刪除。 DROP VIEW
DROP VIEW語句刪除由CREATE VIEW建立的視圖。視圖從數據庫的schema中刪除,表中的數據不會被更改。 EXPLAIN
EXPLAIN命令修飾語是一個非標準的擴展功能,靈感來自PostgreSQL中的相同命令,但操做徹底不一樣。 若EXPLAIN關鍵字出如今任何SQLite的SQL命令以前,則SQLite庫返回不加EXPLAIN時執行該命令所須要使用的虛擬機指令序列,而不是真正執行該命令。關於虛擬機指令的更多信息參見系統結構描述或關於虛擬機的可用代碼。 表達式
這一節與其它的各節有所不一樣。咱們討論的不是一個單一的SQL命令,而是做爲其餘大部分命令的一部分的表達式。 SQLite支持以下的二元運算符,按優先級由高至低排列: ||* / %+ -<< >> & |< <= > >== == != <> INAND OR 所支持的一元運算符: - + ! ~ 注意等號和「不等」號的兩個變種。等號能夠是 =或==. 「不等」號能夠是!=或<>.||爲「鏈接符」——它將兩個字符串鏈接起來。%輸出左邊部分以右邊部分爲模取模獲得的餘數。 二元運算符的結果均爲數字,除了||鏈接符,它給出字符串結果。 文本值(literal value)是一個整數或浮點數。可使用科學計數法。「.」符號老是被看成小數點即便本地設定中用「,」來表示小數點——用「,」表示小數點會形成歧義。字符串常量由字符串加單引號「'」構成。字符串內部的單引號可像Pascal中同樣用兩個單引號來表示。C風格的加反斜線的表示法因爲不是標準SQL而不被支持。BLOB文本是以「x」或「X」開頭的含有十六進制文本信息的文本值。例如: X'53514697465' 文本值一樣能夠爲「NULL」。 表達式中插入文本值佔位符的參數可使用sqlite3_bind API函數在運行時插入。參數能夠是以下幾種形式:
不使用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函數添加到數據庫引擎中。
如下是缺省可用的彙集函數列表。可使用C語言寫出其它的彙集函數而後使用sqlite3_create_function() API函數添加到數據庫引擎中。 在單參數彙集函數中,參數能夠加前綴DISTINCT。這時重複參數會被過濾掉,而後才穿入到函數中。例如,函數「count(distinct X)」返回字段X的不重複非空值的個數,而不是字段X的所有非空值。
INSERT
INSERT語句有兩種基本形式。一種帶有「VALUES」關鍵字,在已有表中插入一個新的行。若不定義字段列表,那麼值的數目將與表中的字段數目相同。不然值的數目須與字段列表中的字段數目相同。不在字段列表中的字段被賦予缺省值或NULL(當未定義缺省值)。 INSERT的第二種形式從SELECT語句中獲取數據。若未定義字段列表,則從SELECT獲得的字段的數目必須與表中的字段數目相同,不然應與定義的字段列表中的字段數目相同。SELECT的每一行結果在表中插入一個新的條目。SELECT能夠是簡單的或者複合的。若是SELECT語句帶有ORDER BY子句,ORDER BY會被忽略。 在使用這一命令時,利用可選的ON CONFLICT子句能夠定義替代的約束衝突斷定算法。更多信息,參見ON CONFLICT。爲了兼容MySQL,可使用REPLACE代替「INSERT OR REPLACE」。 ON CONFLICT子句
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)相同的接口,但在以下重要方面與其它命令不一樣:
可用的pragma命令有以下四個基本類型:
PRAGMA命令語法
使用整數值value的pragma也可使用符號表示,字符串「on」、「true」和「yes」等同於1,「off」、「false」和「no」等同於0。這些字符串大小寫不敏感且無須進行引用。沒法識別的字符串被看成1且不會報錯。value返回時是整數。 用於修改SQLite庫的操做的Pragma
用於查詢數據庫的schema的Pragma
用於查詢/更改版本信息的Pragma
用於庫Debug的Pragma
REINDEX
REINDEX命令用於刪除並從草稿重建索引。當比較順序改變時該命令顯得頗有效。 在第一種形式中,全部附加數據庫中使用該比較順序的索引均被重建。在第二種形式中,[database-name.]table/index-name標識出一個表,全部關聯該表的索引被重建。若標識出索引,則僅僅該索引被刪除並重建。 若不指定database-name而指定表/索引名以及比較順序,只有關聯該比較順序的索引被重建。在重建索引時老是指定database-name能夠消除這一歧義。 REPLACE
REPLACE命令用於替代INSERT的「INSERT OR REPLACE」變體,以更好的兼容MySQL。查看INSERT命令文檔獲取更多信息。 SELECT
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
UPDATE語句用於改變表中所選行的字段值。每一個UPDATE的賦值的等號左邊爲字段名而右邊爲任意表達式。表達式可使用其它字段的值。全部的表達式將在賦值以前求出結果。可使用WHERE子句限定須要改變的行。 在使用這一命令時,利用可選的ON CONFLICT子句能夠定義替代的約束衝突斷定算法。更多信息,參見ON CONFLICT。 VACUUM
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開啓該模式。 |