|
SQLite庫可以解析大部分標準SQL語言。但它也省去了一些特性并且加入了一些自己的新特性。這篇文檔就是試圖描述那些SQLite支持/不支持的SQL語法的。查看關鍵字列表。 如下語法表格中,純文本用藍色粗體顯示。非終極符號為斜體紅色。作為語法一部分的運算符用黑色Roman字體表示。 這篇文檔只是對SQLite實現(xiàn)的SQL語法的綜述,有所忽略。想要得到更詳細的信息,參考源代碼和語法文件“parse.y”。 SQLite執(zhí)行如下的語法:
ALTER TABLE
SQLite版本的的ALTER TABLE命令允許用戶重命名或添加新的字段到已有表中,不能從表中刪除字段。 RENAME TO語法用于重命名表名[database-name.]table-name到new-table-name。這一命令不能用于在附加數(shù)據(jù)庫之間移動表,只能在同一個數(shù)據(jù)庫中對表進行重命名。 若需要重命名的表有觸發(fā)器或索引,在重命名后它們依然屬于該表。但若定義了視圖,或觸發(fā)器執(zhí)行的語句中有提到 表的名字,則它們不會被自動改為使用新的表名。若要進行這一類的修改,則需手工撤銷并使用新的表名重建觸發(fā)器或視圖。 ADD [COLUMN]語法用于在已有表中添加新的字段。新字段總是添加到已有字段列表的末尾。Column-def可以是CREATE TABLE中允許出現(xiàn)的任何形式,且須符合如下限制:
ALTER TABLE語句的執(zhí)行時間與表中的數(shù)據(jù)量無關,它在操作一個有一千萬行的表時的運行時間與操作僅有一行的表時是一樣的。 在對數(shù)據(jù)庫運行ADD COLUMN之后,該數(shù)據(jù)庫將無法由SQLite 3.1.3及更早版本讀取,除非運行VACUUM命令。 ANALYZE
ANALYZE命令令集合關于索引的統(tǒng)計信息并將它們儲存在數(shù)據(jù)庫的一個特殊表中,查詢優(yōu)化器可以用該表來制作更好的索引選擇。若不給出參數(shù),所有附加數(shù)據(jù)庫中的所有索引被分析。若參數(shù)給出數(shù)據(jù)庫名,該數(shù)據(jù)庫中的所有索引被分析。若給出表名 作參數(shù),則只有關聯(lián)該表的索引被分析。 最初的實現(xiàn)將所有的統(tǒng)計信息儲存在一個名叫sqlite_stat1的表中。未來的加強版本中可能會創(chuàng)建名字類似的其它表,只是把“1”改為其它數(shù)字。sqlite_stat1表不能夠被撤銷,但其中的所有內(nèi)容可以被刪除,這是與撤銷該表等效的行為。 ATTACH DATABASEATTACH DATABASE語句將一個已存在的數(shù)據(jù)庫添加到當前數(shù)據(jù)庫連接。若文件名含標點符號,則應用引號引起來。數(shù)據(jù)庫名’main’和’temp’代表主數(shù)據(jù)庫和用于存放臨時表的數(shù)據(jù)庫,它們不能被拆分。拆分數(shù)據(jù)庫使用DETACH DATABASE語句。 你可以讀寫附加數(shù)據(jù)庫,或改變其結構。這是SQLite 3.0提供的新特性。在SQLite 2.8中,改變附加數(shù)據(jù)庫的結構是不允許的。 在附加數(shù)據(jù)庫中添加一個與已有表同名的表是不允許的。但你可以附加帶有與主數(shù)據(jù)庫中的表同名的表的數(shù)據(jù)庫。也可以多次附加同一數(shù)據(jù)庫。 使用database-name.table-name來引用附加數(shù)據(jù)庫中的表。若附加數(shù)據(jù)庫中的表與主數(shù)據(jù)庫的表不重名,則不需加數(shù)據(jù)庫名作為前綴。當數(shù)據(jù)庫被附加時,它的所有不重名的表成為該名字指向的缺省表。之后附加的任意與之同名的表需要加前綴。若“缺省”表被拆分,則最后附加的同名表變?yōu)椤叭笔 北怼?/p> 若主數(shù)據(jù)庫不是“:memory:”,多附加數(shù)據(jù)庫的事務是原子的。若主數(shù)據(jù)庫是“:memory:”則事務在每個獨立文件中依然是原子的。但若主機在改變兩個或更多數(shù)據(jù)庫的COMMIT語句進行時崩潰,則可能一部分文件被改變而其他的保持原樣。附加數(shù)據(jù)庫的原子性的提交 是SQLite 3.0的新特性。在SQLite 2.8中,所有附加數(shù)據(jù)庫的提交類似于主數(shù)據(jù)庫是“:memory:”時的情況。 對附加數(shù)據(jù)庫的數(shù)目有編譯時的限制,最多10個附加數(shù)據(jù)庫。 BEGIN TRANSACTION
從2.0版開始,SQLite支持帶有回退和原子性的提交的事務處理。 可選的事務名稱會被忽略。SQLite目前不允許嵌套事務。 在事務之外,不能對數(shù)據(jù)庫進行更改。如果當前沒有有效的事務,任何修改數(shù)據(jù)庫的命令(基本上除了SELECT以外的所有SQL命令)會自動啟動一個事務。命令結束時,自動啟動的事務會被提交。 可以使用BEGIN命令手動啟動事務。這樣啟動的事務會在下一條COMMIT或ROLLBACK命令之前一直有效。但若數(shù)據(jù)庫關閉或出現(xiàn)錯誤且選用ROLLBACK沖突判定算法時,數(shù)據(jù)庫也會ROLLBACK。查看ON CONFLICT子句獲取更多關于ROLLBACK沖突判定算法的信息。 在SQLite 3.0.8或更高版本中,事務可以是延遲的,即時的或者獨占的?!把舆t的”即是說在數(shù)據(jù)庫第一次被訪問之前不獲得鎖。這樣就會延遲事務,BEGIN語句本身不做任何事情。直到初次讀取或訪問數(shù)據(jù)庫時才獲取鎖。對數(shù)據(jù)庫的初次讀取創(chuàng)建一個SHARED鎖 ,初次寫入創(chuàng)建一個RESERVED鎖。由于鎖的獲取被延遲到第一次需要時,別的線程或進程可以在當前線程執(zhí)行BEGIN語句之后創(chuàng)建另外的事務 寫入數(shù)據(jù)庫。若事務是即時的,則執(zhí)行BEGIN命令后立即獲取RESERVED鎖,而不等數(shù)據(jù)庫被使用。在執(zhí)行BEGIN IMMEDIATE之后,你可以確保其它的線程或進程不能寫入數(shù)據(jù)庫或執(zhí)行BEGIN IMMEDIATE或BEGIN EXCLUSIVE,但其它進程可以讀取數(shù)據(jù)庫。獨占事務在所有的數(shù)據(jù)庫獲取EXCLUSIVE鎖,在執(zhí)行BEGIN EXCLUSIVE之后,你可以確保在當前事務結束前沒有任何其它線程或進程 能夠讀寫數(shù)據(jù)庫。 有關SHARED、RESERVED和EXCLUSIVE鎖可以參見這里。 SQLite 3.0.8的默認行為是創(chuàng)建延遲事務。SQLite 3.0.0到3.0.7中延遲事務是唯一可用的事務類型。SQLite 2.8或更早版本中,所有的事務都是獨占的。 COMMIT命令在所有SQL命令完成之前并不作實際的提交工作。這樣若兩個或更多個SELECT語句在進程中間而執(zhí)行COMMIT時,只有全部SELECT語句結束才進行提交。 執(zhí)行COMMIT可能會返回SQLITE_BUSY錯誤代碼。這就是說有另外一個線程或進程獲取了數(shù)據(jù)庫的讀取鎖,并阻止數(shù)據(jù)庫被改變。當COMMIT獲得該錯誤代碼時,事務依然是活動的,并且在COMMIT可以在當前讀取的線程讀取結束后再次試圖讀取數(shù)據(jù)庫。 END TRANSACTION
從2.0版開始,SQLite支持帶有回退和原子性的提交的事務處理。 可選的事務名稱會被忽略。SQLite目前不允許嵌套事務。 在事務之外,不能對數(shù)據(jù)庫進行更改。如果當前沒有有效的事務,任何修改數(shù)據(jù)庫的命令(基本上除了SELECT以外的所有SQL命令)會自動啟動一個事務。命令結束時,自動啟動的事務會被提交。 可以使用BEGIN命令手動啟動事務。這樣啟動的事務會在下一條COMMIT或ROLLBACK命令之前一直有效。但若數(shù)據(jù)庫關閉或出現(xiàn)錯誤且選用ROLLBACK沖突判定算法時,數(shù)據(jù)庫也會ROLLBACK。查看ON CONFLICT子句獲取更多關于ROLLBACK沖突判定算法的信息。 在SQLite 3.0.8或更高版本中,事務可以是延遲的,即時的或者獨占的?!把舆t的”即是說在數(shù)據(jù)庫第一次被訪問之前不獲得鎖。這樣就會延遲事務,BEGIN語句本身不做任何事情。直到初次讀取或訪問數(shù)據(jù)庫時才獲取鎖。對數(shù)據(jù)庫的初次讀取創(chuàng)建一個SHARED鎖,初次寫入創(chuàng)建一個RESERVED鎖。由于鎖的獲取被延遲到第一次需要時,別的線程或進程可以在當前線程執(zhí)行BEGIN語句之后創(chuàng)建另外的事務寫入數(shù)據(jù)庫。若事務是即時的,則執(zhí)行BEGIN命令后立即獲取RESERVED鎖,而不等數(shù)據(jù)庫被使用。在執(zhí)行BEGIN IMMEDIATE之后,你可以確保其它的線程或進程不能寫入數(shù)據(jù)庫或執(zhí)行BEGIN IMMEDIATE或BEGIN EXCLUSIVE,但其它進程可以讀取數(shù)據(jù)庫。獨占事務在所有的數(shù)據(jù)庫獲取EXCLUSIVE鎖,在執(zhí)行BEGIN EXCLUSIVE之后,你可以確保在當前事務結束前沒有任何其它線程或進程能夠讀寫數(shù)據(jù)庫。 有關SHARED、RESERVED和EXCLUSIVE鎖可以參見這里。 SQLite 3.0.8的默認行為是創(chuàng)建延遲事務。SQLite 3.0.0到3.0.7中延遲事務是唯一可用的事務類型。SQLite 2.8或更早版本中,所有的事務都是獨占的。 COMMIT命令在所有SQL命令完成之前并不作實際的提交工作。這樣若兩個或更多個SELECT語句在進程中間而執(zhí)行COMMIT時,只有全部SELECT語句結束才進行提交。 執(zhí)行COMMIT可能會返回SQLITE_BUSY錯誤代碼。這就是說有另外一個線程或進程獲取了數(shù)據(jù)庫的讀取鎖,并阻止數(shù)據(jù)庫被改變。當COMMIT獲得該錯誤代碼時,事務依然是活動的,并且在COMMIT可以在當前讀取的線程讀取結束后再次試圖讀取數(shù)據(jù)庫。 注釋
注釋不是SQL命令,但會出現(xiàn)在SQL查詢中。它們被解釋器處理為空白部分。它們可以在任何空白可能存在的地方開始 ,即使是在跨越多行的表達式中。 SQL風格的注釋僅對當前行有效。 C風格的注釋可以跨越多行。若沒有結束符號,注釋的范圍將一直延伸到輸入末尾,且不會引起報錯。新的SQL語句可以從多行注釋結束的地方開始。C風格注釋可以嵌入任何空白可以出現(xiàn)的地方,包括表達式內(nèi),或其他SQL語句中間, 并且C風格的注釋不互相嵌套。SQL風格的注釋出現(xiàn)在C風格注釋中時將被忽略。 COPY
COPY命令在SQLite 2.8及更早的版本中可用。SQLite 3.0刪除了這一命令,因為在混合的UTF-8/16環(huán)境中對它進行支持是很復雜的。在3.0版本中,命令行解釋器包含新的.import命令,用以替代COPY。 COPY命令是用于將大量數(shù)據(jù)插入表的一個插件。它模仿PostgreSQL中的相同命令而來。事實上,SQLite的COPY 命令就是為了能夠讀取PostgreSQL的備份工具pg_dump的輸出從而能夠?qū)ostgreSQL的數(shù)據(jù)輕松轉換到SQLite中而設計的。 table-name是將要導入數(shù)據(jù)的一個已存在的表的名字。filename是一個字符串或標識符,用于說明作為數(shù)據(jù)來源的文件。filename可以使用STDIN從標準輸入流中獲取數(shù)據(jù)。 輸入文件的每一行被轉換成一條單獨的記錄導入表中。字段用制表符分開。若某個字段的數(shù)據(jù)中出現(xiàn)制表符,則前面被添加反斜線“/”符號。數(shù)據(jù)中的反斜線則被替換為兩條反斜線??蛇x的USING DELIMITERS子句可給出一個與制表符不同 的分界符。 若字段由“/N”組成,則被賦以空值NULL。 使用這一命令時,利用可選的ON CONFLICT子句可以定義替代的約束沖突判定算法。更多信息,參見 ON CONFLICT。 當輸入數(shù)據(jù)源是STDIN,輸入將終止于一行僅包含一個反斜線和一個點的輸入:“/.”。 CREATE INDEX
CREATE INDEX命令由“CREATE INDEX”關鍵字后跟新索引的名字,關鍵字“ON”,待索引表的名字,以及括弧內(nèi)的用于索引鍵的字段列表構成。每個字段名可以跟隨“ASC”或“DESC”關鍵字說明排序法則,但在當前版本中排序法則被忽略。排序總是按照上升序。 每個字段名后跟COLLATE子句定義文本記錄的比較順序。缺省的比較順序是由CREATE TABLE語句說明的比較順序。若不定義比較順序,則使用內(nèi)建的二進制比較順序。 附加到單個表上的索引數(shù)目沒有限制,索引中的字段數(shù)也沒有限制。 若UNIQUE關鍵字出現(xiàn)在CREATE和INDEX之間,則不允許重名的索引記錄。試圖插入重名記錄將會導致錯誤。 每條CREATE INDEX語句的文本儲存于sqlite_master或sqlite_temp_master表中,取決于被索引的表是否臨時表。 每次打開數(shù)據(jù)庫時,所有的CREATE INDEX語句從sqlite_master表中讀出,產(chǎn)生SQLite的索引樣式的內(nèi)部結構。 若使用可選的IF NOT EXISTS子句,且存在同名索引,則該命令無效。 使用DROP INDEX命令刪除索引。 CREATE TABLE
CREATE TABLE語句基本上就是“CREATE TABLE”關鍵字后跟一個新的表名以及括號內(nèi)的一堆定義和約束。表名可以是字符串或者標識符。以“sqlite_”開頭的表名是留給數(shù)據(jù)庫引擎使用的。 每個字段的定義是字段名后跟字段的數(shù)據(jù)類型,接著是一個或多個的字段約束。字段的數(shù)據(jù)類型并不限制字段中可以存放的數(shù)據(jù)??梢圆榭?span style="color: #ff3434;">SQLite3的數(shù)據(jù)類型獲取更多信息。UNIQUE約束為指定的字段創(chuàng)建索引,該索引須含有唯一鍵。COLLATE子句說明在比較字段的 文字記錄時所使用的排序函數(shù)。缺省使用內(nèi)嵌的BINARY排序函數(shù)。 DEFAULT約束說明在使用INSERT插入字段時所使用的缺省值。該值可以是NULL,字符串常量或一個數(shù)。從3.1.0版開始,缺省值也可以是以下特殊的與事件無關的關鍵字CURRENT_TIME、CURRENT_DATE或CURRENT_TIMESTAMP。若缺省值為NULL、字符串常量或數(shù),在執(zhí)行未指明字段值的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只是在相應字段上創(chuàng)建一個UNIQUE索引。然而,若主鍵定義在單一的INTEGER類型的字段上,則該字段在內(nèi)部被用作表的B-Tree鍵。這即是說字段僅能容納唯一整數(shù)值。(在除此之外的其它情況下,SQLite忽略數(shù)據(jù)類型的說明 ,允許任何類型的數(shù)據(jù)放入字段中,不管該字段被聲明為什么數(shù)據(jù)類型。)若一個表中不含一個INTEGER PRIMARY KEY字段,則B-Tree鍵為自動產(chǎn)生的整數(shù)。一行的B-Tree鍵可以通過如下特殊的名字“ROWID”、“OID”或“_ROWID_”進行訪問,不論是否有INTEGER PRIMARY KEY存在。INTEGER PRIMARY KEY字段可以使用關鍵字AUTOINCREMENT聲明。AUTOINCREMENT關鍵字修改了B-Tree鍵自動產(chǎn)生的方式。B-Tree鍵的生成的其它信息可以在這里找到。 若“TEMP”或“TEMPORARY”關鍵字出現(xiàn)在“CREATE”和“TABLE”之間,則所建立的表僅在當前數(shù)據(jù)庫連接可見,并在斷開連接時自動被刪除。在臨時表上建立的任何索引也是臨時的。臨時表和索引單獨存儲在與主數(shù)據(jù)庫文件不同的文件中。 若說明了,則表在該數(shù)據(jù)庫中被創(chuàng)建。同時聲明和TEMP關鍵字會出錯,除非 是“temp”。若不聲明數(shù)據(jù)庫名,也不使用TEMP關鍵字,則表創(chuàng)建于主數(shù)據(jù)庫中。 在每個約束后跟可選的ON CONFLICT子句可以定義替代的約束沖突判定算法。 缺省為ABORT。同一個表中的不同約束可以使用不同的缺省沖突判定算法。若一條COPY、INSERT或UPDATE命令指定了不同的沖突判定算法,則該算法將替代CREATE TABLE語句中說明的缺省算法。更多信息,參見ON CONFLICT。 3.3.0版支持CHECK約束。在3.3.0之前,CHECK約束被解析但不執(zhí)行。 表中的字段數(shù)或約束數(shù)沒有任何限制。在2.8版中,單行數(shù)據(jù)的總數(shù)被限制為小于1 megabytes。而在3.0中則消除了限制。 CREATE TABLE AS形式定義表為一個查詢的結果集。表的字段名字即是結果中的字段名字。 每條CREATE TABLE語句的文本都儲存在sqlite_master表中。每當數(shù)據(jù)庫被打開,所有的CREATE TABLE語句從 sqlite_master表中讀出,構成表結構的SQLite內(nèi)部實現(xiàn)。若原始命令為CREATE TABLE AS則合成出等效的CREATE TABLE語句并儲存于sqlite_master表中代替原命令。CREATE TEMPORARY TABLE語句文本儲存于sqlite_temp_master表中。 若在命令中使用可選的IF NOT EXISTS子句且存在同名的另一個表,則當前的命令無效。 刪除表可以使用DROP TABLE語句。
CREATE TRIGGER
CREATE TRIGGER語句用于向數(shù)據(jù)庫schema中添加觸發(fā)器。觸發(fā)器是一些在特定的數(shù)據(jù)庫事件(database-event)發(fā)生時自動進行的數(shù)據(jù)庫操作(trigger-action)。 觸發(fā)器可由在特殊表上執(zhí)行的DELETE、INSERT、UPDATE等語句觸發(fā),或UPDATE表中特定的字段時觸發(fā)。 現(xiàn)在SQLite僅支持FOR EACH ROW觸發(fā)器,不支持FOR EACH STATEMENT觸發(fā)。因此可以不用明確說明FOR EACH ROW。FOR EACH ROW的意思是由trigger-steps說明的SQL語句可能在(由WHEN子句決定的)數(shù)據(jù)庫插入,更改或刪除的每一行觸發(fā)trigger。 WHEN子句和trigger-steps可以使用“NEW.column-name”和“OLD.column-name”的引用形式訪問正在被插入,更改或刪除的行的元素,column-name是觸發(fā)器關聯(lián)的表中的字段名。OLD和NEW引用只在觸發(fā)器與之相關的trigger-event處可用,例如:
當使用WHEN子句,trigger-steps只在WHEN子句為真的行執(zhí)行。不使用WHEN時則在所有行執(zhí)行。 trigger-time決定了trigger-steps執(zhí)行的時間,它是相對于關聯(lián)行的插入、刪除和修改而言的。 作為的一部分trigger-step的UPDATE或INSERT可以使用ON CONFLICT子句。但若觸發(fā)trigger的語句使用了ON CONFLICT子句,則覆蓋前述的ON CONFLICT子句所定義的沖突處理方法。 關聯(lián)表被撤銷時觸發(fā)器被自動刪除。 不僅在表上,在視圖上一樣可以創(chuàng)建觸發(fā)器,在CREATE TRIGGER語句中使用INSTEAD OF即可。若視圖上定義了一個或多個ON INSERT、ON DELETE、ON UPDATE觸發(fā)器,則相應地對視圖執(zhí)行INSERT、DELETE或UPDATE語句不會出錯,而會觸發(fā)關聯(lián)的觸發(fā)器。視圖關聯(lián)的表不會被修改。(除了由觸發(fā)器進行的修改操作)。 例子: 假設“customers”表存儲了客戶信息,“orders”表存儲了訂單信息,下面的觸發(fā)器確保當用戶改變地址時所有的關聯(lián)訂單地址均進行相應改變: CREATE TRIGGER update_customer_address UPDATE OF address ON customers BEGIN UPDATE orders SET address = new.address WHERE customer_name = old.name; END; 定義了該觸發(fā)器后執(zhí)行如下語句: UPDATE customers SET address = ’1 Main St.’ WHERE name = ’Jack Jones’; 會使下面的語句自動執(zhí)行: UPDATE orders SET address = ’1 Main St.’ WHERE customer_name = ’Jack Jones’; 注意,目前在有INTEGER PRIMARY KEY域的表上觸發(fā)器可能工作不正常。若BEFORE觸發(fā)器修改了一行的INTEGER PRIMARY KEY域,而該域?qū)⒂捎|發(fā)該觸發(fā)器的語句進行修改,則可能根本不會修改該域??梢杂肞RIMARY KEY字段代替INTEGER PRIMARY KEY字段來解決上述問題。 一個特殊的SQL函數(shù)RAISE()可用于觸發(fā)器程序,使用如下語法:
當觸發(fā)器程序執(zhí)行中調(diào)用了上述前三個之一的形式時,則執(zhí)行指定的ON CONFLICT進程(ABORT、FAIL或者ROLLBACK)且終止當前查詢,返回一個SQLITE_CONSTRAINT錯誤并說明錯誤信息。 當調(diào)用RAISE(IGNORE),當前觸發(fā)器程序的余下部分,觸發(fā)該觸發(fā)器的語句和任何之后的觸發(fā)器程序被忽略并且不恢復對數(shù)據(jù)庫的已有改變。若觸發(fā)觸發(fā)器的語句是一個觸發(fā)器程序本身的一部分,則原觸發(fā)器程序從下一步起繼續(xù)執(zhí)行。 使用DROP TRIGGER刪除觸發(fā)器。 CREATE VIEW
CREATE VIEW命令為一個包裝好的SELECT語句命名。當創(chuàng)建了一個視圖,它可以用于其他SELECT的FROM字句中代替表名。 若“TEMP”或“TEMPORARY”關鍵字出現(xiàn)在“CREATE”和“VIEW”之間,則創(chuàng)建的視圖僅對打開數(shù)據(jù)庫的進程可見,且在數(shù)據(jù)庫關閉時自動刪除。 若指定了則視圖在指定的數(shù)據(jù)庫中創(chuàng)建。同時使用和TEMP關鍵字會導致錯誤,除非是“temp”。若不聲明數(shù)據(jù)庫名,也不使用TEMP關鍵字,則視圖創(chuàng)建于主數(shù)據(jù)庫中。 你不能對視圖使用COPY、DELETE、INSERT或UPDATE,視圖在SQLite中是只讀的。多數(shù)情況下你可以在視圖上創(chuàng)建TRIGGER來達到相同目的。用DROP VIEW命令來刪除視圖。 DELETE
DELETE命令用于從表中刪除記錄。命令包含“DELETE FROM”關鍵字以及需要刪除的記錄所在的表名。 若不使用WHERE子句,表中的所有行將全部被刪除。否則僅刪除符合條件的行。 DETACH DATABASE
該語句拆分一個之前使用ATTACH DATABASE語句附加的數(shù)據(jù)庫連接??梢允褂貌煌拿侄啻胃郊油粩?shù)據(jù)庫,并且拆分一個連接不會影響其他連接。 若SQLite在事務進行中,該語句不起作用。 DROP INDEX
DROP INDEX語句刪除由CREATE INDEX語句創(chuàng)建的索引。索引將從數(shù)據(jù)庫結構和磁盤文件中完全刪除,唯一的恢復方法是重新輸入相應的CREATE INDEX命令。 DROP TABLE語句在缺省模式下不減小數(shù)據(jù)庫文件的大小。空間會留給后來的INSERT語句使用。要釋放刪除產(chǎn)生的空間,可以使用VACUUM命令。若AUTOVACUUM模式開啟,則空間會自動被DROP INDEX釋放。 DROP TABLE
DROP TABLE語句刪除由CREATE TABLE語句創(chuàng)建的表。表將從數(shù)據(jù)庫結構和磁盤文件中完全刪除,且不能恢復。該表的所有索引也同時被刪除。 DROP TABLE語句在缺省模式下不減小數(shù)據(jù)庫文件的大小??臻g會留給后來的INSERT語句使用。要釋放刪除產(chǎn)生的空間,可以使用VACUUM命令。若AUTOVACUUM模式開啟,則空間會自動被DROP TABLE釋放。 若使用可選的IF EXISTS子句,在刪除的表不存在時就不會報錯。 DROP TRIGGER
DROP TRIGGER語句刪除由CREATE TRIGGER創(chuàng)建的觸發(fā)器。觸發(fā)器從數(shù)據(jù)庫的schema中刪除。注意當關聯(lián)的表被撤消時觸發(fā)器自動被刪除。 DROP VIEW
DROP VIEW語句刪除由CREATE VIEW創(chuàng)建的視圖。視圖從數(shù)據(jù)庫的schema中刪除,表中的數(shù)據(jù)不會被更改。 EXPLAIN
EXPLAIN命令修飾語是一個非標準的擴展功能,靈感來自PostgreSQL中的相同命令,但操作完全不同。 若EXPLAIN關鍵字出現(xiàn)在任何SQLite的SQL命令之前,則SQLite庫返回不加EXPLAIN時執(zhí)行該命令所需要使用的虛擬機指令序列,而不是真正執(zhí)行該命令。關于虛擬機指令的更多信息參見系統(tǒng)結構描述或關于虛擬機的可用代碼。 表達式
這一節(jié)與其它的各節(jié)有所不同。我們討論的不是一個單一的SQL命令,而是作為其他大部分命令的一部分的表達式。 SQLite支持如下的二元運算符,按優(yōu)先級由高至低排列:
所支持的一元運算符:
注意等號和“不等”號的兩個變種。等號可以是 =或==. “不等”號可以是!=或<>. ||為“連接符”——它將兩個字符串連接起來。 %輸出左邊部分以右邊部分為模取模得到的余數(shù)。 二元運算符的結果均為數(shù)字,除了||連接符,它給出字符串結果。 文本值(literal value)是一個整數(shù)或浮點數(shù)??梢允褂每茖W計數(shù)法?!?”符號總是被當作小數(shù)點即使本地設定中用“,”來表示小數(shù)點——用“,”表示小數(shù)點會造成歧義。字符串常量由字符串加單引號“'”構成。字符串內(nèi)部的單引號可像Pascal中一樣用兩個單引號來表示。C風格的加反斜線的表示法由于不是標準SQL而不被支持。BLOB文本是以“x”或“X”開頭的含有十六進制文本信息的文本值。例如: X'53514697465' 文本值同樣可以為“NULL”。 表達式中插入文本值占位符的參數(shù)可以使用sqlite3_bind API函數(shù)在運行時插入。參數(shù)可以是如下幾種形式:
不使用sqlite3_bind賦值的參數(shù)被視為NULL。 LIKE運算符進行模式匹配比較。運算符右邊為進行匹配的模式而左邊為需進行匹配的字符串。模式中的百分號%匹配結果中的零或任意多個字符。下劃線_匹配任意單個字符。其他的任意字符匹配本身或等同的大/小寫字符。(即不區(qū)分大小寫的匹配)。(一個bug:SQLite僅對7-bit拉丁字符支持不區(qū)分大小寫匹配。這是由于LIKE運算符對8-bit ISO8859字符或UTF-8字符是大小寫敏感的。例如,表達式'a' LIKE 'A'的值為真而'?' LIKE '?'為假)。 如果使用可選的ESCAPE子句,則跟隨ESCAPE關鍵字的必須是一個有一個字符的字符串。這一字符(逃逸字符)可用于LIKE模式中,以代替百分號或下劃線。逃逸字符后跟百分號,下劃線或它本身代表字符串中的百分號,下劃線或逃逸字符。插入的LIKE運算符功能通過調(diào)用用戶函數(shù)like(X,Y)來實現(xiàn)。 當使用可選的ESCAPE子句,它對函數(shù)給出第三個參數(shù),LIKE的功能可以通過重載SQL函數(shù)like()進行改變。 GLOB運算符與LIKE相似,但它使用Unix文件globbing語法作為通配符。還有一點不同是GLOB對大小寫敏感。GLOB和LIKE都可以前綴NOT關鍵字構成相反的意思。插入的GLOB運算符功能通過調(diào)用用戶函數(shù)glob(X,Y)可以通過重載函數(shù)改變GLOB的功能。 REGEXP運算符是用戶函數(shù)regexp()的一個特殊的代表符號。缺省情況下regexp()函數(shù)不被定義,所以使用REGEXP運算符會報錯。當運行時存在用戶定義的“regexp”函數(shù)的定義,則調(diào)用該函數(shù)以實現(xiàn)REGEXP運算符功能。 字段名可以是CREATE TABLE語句定義的任何名字或如下幾個特殊標識符之一“ROWID”、“OID”以及“_ROWID_”。這些特殊標識符均代表每個表每一行關聯(lián)的那個唯一隨機整數(shù)鍵“row key”。僅僅在CREATE TABLE語句沒有對這些特殊標識符的真實字段予以定義的情況下,它們才代表“row key”。它們與只讀字段類似,可以像任何正常字段一樣使用,除了在UPDATE或INSERT語句中(即是說你不能添加或更改row key)?!癝ELECT * ...”不返回row key。 SELECT語句可以在表達式中出現(xiàn),作為IN運算符的右邊運算量,作為一個純量,或作為EXISTS運算符的運算量。當作純量或IN的運算量時,SELECT語句的結果僅允許有一個字段,可以使用復合的SELECT(用UNION或 EXCEPT等關鍵字連接)。作為EXISTS運算符的運算量時,SELECT結果中的字段被忽略,在結果為空時表達式為假,反之為真。若SELECT表達式代表的查詢中不含有引用值的部分,則它將在處理其它事務之前被計算,并且結果在必要時會被重復使用。若SELECT表達式含從其它查詢中得到的變量,在每一次使用時該表達式均被重新計算。 當SELECT作為IN運算符的右運算量,在左邊的運算量是SELECT產(chǎn)生的任意一個值時,表達式返回TRUE。IN運算符前可以加NOT構成相反的意思。 當SELECT與表達式一同出現(xiàn)且不在IN的右邊,則SELECT結果的第一行作為表達式中使用的值。SELECT返回的結果在第一行以后的部分被忽略。返回結果為空時SELECT語句的值為NULL。 CAST表達式將的數(shù)據(jù)類型改為聲明的類型??梢允荂REATE TABLE語句字段定義部分定義的對該字段有效的任意非空數(shù)據(jù)類型。 表達式支持簡單函數(shù)和聚集函數(shù)。簡單函數(shù)直接從輸入獲得結果,可用于任何表達式中。聚集函數(shù)使用結果集中的所有行計算結果,僅用于SELECT語句中。 T下面這些函數(shù)是缺省可用的??梢允褂肅語言寫出其它的函數(shù)然后使用sqlite3_create_function() API函數(shù)添加到數(shù)據(jù)庫引擎中。
以下是缺省可用的聚集函數(shù)列表??梢允褂肅語言寫出其它的聚集函數(shù)然后使用sqlite3_create_function() API函數(shù)添加到數(shù)據(jù)庫引擎中。 在單參數(shù)聚集函數(shù)中,參數(shù)可以加前綴DISTINCT。這時重復參數(shù)會被過濾掉,然后才穿入到函數(shù)中。例如,函數(shù)“count(distinct X)”返回字段X的不重復非空值的個數(shù),而不是字段X的全部非空值。
INSERT
INSERT語句有兩種基本形式。一種帶有“VALUES”關鍵字,在已有表中插入一個新的行。若不定義字段列表,那么值的數(shù)目將與表中的字段數(shù)目相同。否則值的數(shù)目須與字段列表中的字段數(shù)目相同。不在字段列表中的字段被賦予缺省值或NULL(當未定義缺省值)。 INSERT的第二種形式從SELECT語句中獲取數(shù)據(jù)。若未定義字段列表,則從SELECT得到的字段的數(shù)目必須與表中的字段數(shù)目相同,否則應與定義的字段列表中的字段數(shù)目相同。SELECT的每一行結果在表中插入一個新的條目。SELECT可以是簡單的或者復合的。如果SELECT語句帶有ORDER BY子句,ORDER BY會被忽略。 在使用這一命令時,利用可選的ON CONFLICT子句可以定義替代的約束沖突判定算法。更多信息,參見ON CONFLICT。為了兼容MySQL,可以使用REPLACE代替“INSERT OR REPLACE”。 ON CONFLICT子句
ON CONFLICT子句不是獨立的SQL命令。這是一條可以出現(xiàn)在許多其他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。選項含義如下:
INSERT或UPDATE的OR子句定義的算法會覆蓋CREATE TABLE所定義的。ABORT算法將在沒有定義任何算法時缺省使用。 SQLite支持的編譯指令(Pragma)PRAGMA命令是用于修改SQlite庫或查詢SQLite庫內(nèi)部數(shù)據(jù)(non-table)的特殊命令。PRAGMA 命令使用與其它SQLite命令(例如:SELECT、INSERT)相同的接口,但在如下重要方面與其它命令不同:
可用的pragma命令有如下四個基本類型:
PRAGMA命令語法
使用整數(shù)值value的pragma也可以使用符號表示,字符串“on”、“true”和“yes”等同于1,“off”、“false”和“no”等同于0。這些字符串大小寫不敏感且無須進行引用。無法識別的字符串被當作1且不會報錯。value返回時是整數(shù)。 用于修改SQLite庫的操作的Pragma
用于查詢數(shù)據(jù)庫的schema的Pragma
用于查詢/更改版本信息的Pragma
用于庫Debug的Pragma
REINDEX
REINDEX命令用于刪除并從草稿重建索引。當比較順序改變時該命令顯得很有效。 在第一種形式中,所有附加數(shù)據(jù)庫中使用該比較順序的索引均被重建。在第二種形式中,[database-name.]table/index-name標識出一個表,所有關聯(lián)該表的索引被重建。若標識出索引,則僅僅該索引被刪除并重建。 若不指定database-name而指定表/索引名以及比較順序,只有關聯(lián)該比較順序的索引被重建。在重建索引時總是指定database-name可以消除這一歧義。 REPLACE
REPLACE命令用于替代INSERT的“INSERT OR REPLACE”變體,以更好的兼容MySQL。查看INSERT命令文檔獲取更多信息。 SELECT
SELECT語句用于查詢數(shù)據(jù)庫。一條SELECT命令的返回結果是零或多行每行有固定字段數(shù)的數(shù)據(jù)。字段的數(shù)目由在SELECT和FROM之間的表達式列表定義。任意的表達式都可以被用作結果。若表達式是 *則表示所有表的所有字段。若表達式是表的名字后接.*則結果為該表中的所有字段。 DISTINCT關鍵字的使用會使返回的結果是原結果的一個不含相同行的子集。NULL值被認為是相同的。缺省行為是返回所有的行,為清楚起見可以使用關鍵字ALL。 查詢對FROM之后定義的一個或多個表進行。若多個表用逗號連接,則查詢針對它們的交叉連接。所有的SQL-92連接語法均可以用于定義連接。圓括號中的副查詢可能被FROM子句中的任意表名替代。當結果中僅有一行包含表達式列表中的結果的行時,整個的FROM子句會被忽略。 WHERE子句可以限定查詢操作的行數(shù)目。 GROUP BY子句將一行或多行結果合成單行輸出。當結果有聚集函數(shù)時這將尤其有用。GROUP BY子句的表達式不須是出現(xiàn)在結果中的表達式。HAVING子句與WHERE相似,只是HAVING用于過濾分組創(chuàng)建的行。HAVING子句可能包含值,甚至是不出現(xiàn)在結果中的聚集函數(shù)。 ORDER BY子句對所得結果根據(jù)表達式排序。表達式無須是簡單SELECT的結果,但在復合SELECT中每個表達式必須精確對應一個結果字段。每個表達式可能跟隨一個可選的COLLATE關鍵字以及用于排序文本的比較函數(shù)名稱和/或關鍵字ASC或DESC,用于說明排序規(guī)則。 LIMIT子句限定行數(shù)的最大值。負的LIMIT表示無上限。后跟可選的OFFSET說明跳過結果集中的前多少行。在一個復合查詢中,LIMIT子句只允許出現(xiàn)在最終SELECT語句中。限定對于所有的查詢均適用,而不僅僅是添加了LIMIT子句的那一行。注意OFFSET關鍵字用于LIMIT子句中,則限制值是第一個數(shù)字,而偏移量(offset)是第二個數(shù)字。若用逗號替代OFFSET關鍵字,則偏移量是第一個數(shù)字而限制值是第二個數(shù)字。這是為了加強對遺留的SQL數(shù)據(jù)庫的兼容而有意造成的矛盾。 復合的SELECT由兩個或更多簡單SELECT經(jīng)由UNION、UNION ALL、INTERSECT、EXCEPT中的一個運算符連接而成。在一個復合SELECT中,各個SELECT需指定相同個數(shù)的結果字段。僅允許一個ORDER BY子句出現(xiàn)在SELECT的末尾。UNION和UNION ALL運算符從左至右將所有SELECT的結果合成一個大的表。二者的區(qū)別在于UNION的所有結果行是不相同的而UNION ALL允許重復行。INTERSECT運算符取左右兩個SELECT結果的交。EXCEPT從左邊SELECT的結果中除掉右邊SELECT的結果。三個或更多SELECT復合時,它們從左至右結合。 UPDATE
UPDATE語句用于改變表中所選行的字段值。每個UPDATE的賦值的等號左邊為字段名而右邊為任意表達式。表達式可以使用其它字段的值。所有的表達式將在賦值之前求出結果??梢允褂肳HERE子句限定需要改變的行。 在使用這一命令時,利用可選的ON CONFLICT子句可以定義替代的約束沖突判定算法。更多信息,參見ON CONFLICT。 VACUUM
VACUUM命令是SQLite的一個擴展功能,模仿PostgreSQL中的相同命令而來。若調(diào)用VACUUM帶一個表名或索引名,則將整理該表或索引。在SQLite 1.0中,VACUUM命令調(diào)用gdbm_reorganize()整理后端數(shù)據(jù)庫文件。 SQLITE 2.0.0中去掉了GDBM后端,VACUUM無效。在2.8.1版中,VACUUM被重新實現(xiàn)。現(xiàn)在索引名或表名被忽略。 當數(shù)據(jù)庫中的一個對象(表、索引或觸發(fā)器)被撤銷,會留下空白的空間。它使數(shù)據(jù)庫比需要的大小更大,但能加快插入速度。實時的插入和刪除會使得數(shù)據(jù)庫文件結構混亂,減慢對數(shù)據(jù)庫內(nèi)容訪問的速度。VACUUM命令復制主數(shù)據(jù)庫文件到臨時數(shù)據(jù)庫并從臨時數(shù)據(jù)庫重新載入主數(shù)據(jù)庫,以整理數(shù)據(jù)庫文件。這將除去空白頁,使表數(shù)據(jù)彼此相鄰排列,并整理數(shù)據(jù)庫文件結構。不能對附加數(shù)據(jù)庫文件進行以上操作。 若當前有活動事務,該命令無法起作用。對于In-Memory數(shù)據(jù)庫,該命令無效。 SQLite 3.1中,可以通過使用auto-vacuum模式取代VACUUM命令,使用auto_vacuum pragma開啟該模式。 |
|
|