电竞比分网-中国电竞赛事及体育赛事平台

分享

SQLite的SQL語法

 點點滴滴 2012-03-31

SQLite的SQL語法

4765人閱讀 評論(0) 收藏 舉報

SQLite庫可以解析大部分標準SQL語言。但它也省去了一些特性并且加入了一些自己的新特性。這篇文檔就是試圖描述那些SQLite支持/不支持的SQL語法的。查看關鍵字列表。

如下語法表格中,純文本用藍色粗體顯示。非終極符號為斜體紅色。作為語法一部分的運算符用黑色Roman字體表示。

這篇文檔只是對SQLite實現(xiàn)的SQL語法的綜述,有所忽略。想要得到更詳細的信息,參考源代碼和語法文件“parse.y”。

SQLite執(zhí)行如下的語法:

ALTER TABLE

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

SQLite版本的的ALTER TABLE命令允許用戶重命名或添加新的字段到已有表中,不能從表中刪除字段。

RENAME TO語法用于重命名表名[database-name.]table-namenew-table-name。這一命令不能用于在附加數(shù)據(jù)庫之間移動表,只能在同一個數(shù)據(jù)庫中對表進行重命名。

若需要重命名的表有觸發(fā)器或索引,在重命名后它們依然屬于該表。但若定義了視圖,或觸發(fā)器執(zhí)行的語句中有提到 表的名字,則它們不會被自動改為使用新的表名。若要進行這一類的修改,則需手工撤銷并使用新的表名重建觸發(fā)器或視圖。

ADD [COLUMN]語法用于在已有表中添加新的字段。新字段總是添加到已有字段列表的末尾。Column-def可以是CREATE TABLE中允許出現(xiàn)的任何形式,且須符合如下限制:

  • 字段不能有主鍵或唯一約束。
  • 字段不能有這些缺省值:CURRENT_TIME, CURRENT_DATE或CURRENT_TIMESTAMP
  • 若定義了NOT NULL約束,則字段必須有一個非空的缺省值。

ALTER TABLE語句的執(zhí)行時間與表中的數(shù)據(jù)量無關,它在操作一個有一千萬行的表時的運行時間與操作僅有一行的表時是一樣的。

在對數(shù)據(jù)庫運行ADD COLUMN之后,該數(shù)據(jù)庫將無法由SQLite 3.1.3及更早版本讀取,除非運行VACUUM命令。

ANALYZE

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

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 DATABASE

ATTACH 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

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目前不允許嵌套事務。

在事務之外,不能對數(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

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目前不允許嵌套事務。

在事務之外,不能對數(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ù)庫。

注釋

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

注釋不是SQL命令,但會出現(xiàn)在SQL查詢中。它們被解釋器處理為空白部分。它們可以在任何空白可能存在的地方開始 ,即使是在跨越多行的表達式中。

SQL風格的注釋僅對當前行有效。

C風格的注釋可以跨越多行。若沒有結束符號,注釋的范圍將一直延伸到輸入末尾,且不會引起報錯。新的SQL語句可以從多行注釋結束的地方開始。C風格注釋可以嵌入任何空白可以出現(xiàn)的地方,包括表達式內(nèi),或其他SQL語句中間, 并且C風格的注釋不互相嵌套。SQL風格的注釋出現(xiàn)在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環(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

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”,待索引表的名字,以及括弧內(nèi)的用于索引鍵的字段列表構成。每個字段名可以跟隨“ASC”或“DESC”關鍵字說明排序法則,但在當前版本中排序法則被忽略。排序總是按照上升序。

每個字段名后跟COLLATE子句定義文本記錄的比較順序。缺省的比較順序是由CREATE TABLE語句說明的比較順序。若不定義比較順序,則使用內(nèi)建的二進制比較順序。

附加到單個表上的索引數(shù)目沒有限制,索引中的字段數(shù)也沒有限制。

若UNIQUE關鍵字出現(xiàn)在CREATE和INDEX之間,則不允許重名的索引記錄。試圖插入重名記錄將會導致錯誤。

每條CREATE INDEX語句的文本儲存于sqlite_mastersqlite_temp_master表中,取決于被索引的表是否臨時表。 每次打開數(shù)據(jù)庫時,所有的CREATE INDEX語句從sqlite_master表中讀出,產(chǎn)生SQLite的索引樣式的內(nèi)部結構。

若使用可選的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”關鍵字后跟一個新的表名以及括號內(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

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語句用于向數(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處可用,例如:

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

當使用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ā)器程序,使用如下語法:

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

當觸發(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

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

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

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

DELETE命令用于從表中刪除記錄。命令包含“DELETE FROM”關鍵字以及需要刪除的記錄所在的表名。

若不使用WHERE子句,表中的所有行將全部被刪除。否則僅刪除符合條件的行。

DETACH DATABASE

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

該語句拆分一個之前使用ATTACH DATABASE語句附加的數(shù)據(jù)庫連接??梢允褂貌煌拿侄啻胃郊油粩?shù)據(jù)庫,并且拆分一個連接不會影響其他連接。

若SQLite在事務進行中,該語句不起作用。

DROP INDEX

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

DROP INDEX語句刪除由CREATE INDEX語句創(chuàng)建的索引。索引將從數(shù)據(jù)庫結構和磁盤文件中完全刪除,唯一的恢復方法是重新輸入相應的CREATE INDEX命令。

DROP TABLE語句在缺省模式下不減小數(shù)據(jù)庫文件的大小。空間會留給后來的INSERT語句使用。要釋放刪除產(chǎn)生的空間,可以使用VACUUM命令。若AUTOVACUUM模式開啟,則空間會自動被DROP INDEX釋放。

DROP TABLE

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

DROP TABLE語句刪除由CREATE TABLE語句創(chuàng)建的表。表將從數(shù)據(jù)庫結構和磁盤文件中完全刪除,且不能恢復。該表的所有索引也同時被刪除。

DROP TABLE語句在缺省模式下不減小數(shù)據(jù)庫文件的大小??臻g會留給后來的INSERT語句使用。要釋放刪除產(chǎn)生的空間,可以使用VACUUM命令。若AUTOVACUUM模式開啟,則空間會自動被DROP TABLE釋放。

若使用可選的IF EXISTS子句,在刪除的表不存在時就不會報錯。

DROP TRIGGER

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

DROP TRIGGER語句刪除由CREATE TRIGGER創(chuàng)建的觸發(fā)器。觸發(fā)器從數(shù)據(jù)庫的schema中刪除。注意當關聯(lián)的表被撤消時觸發(fā)器自動被刪除。

DROP VIEW

sql-command ::= DROP VIEW view-name

DROP VIEW語句刪除由CREATE VIEW創(chuàng)建的視圖。視圖從數(shù)據(jù)庫的schema中刪除,表中的數(shù)據(jù)不會被更改。

EXPLAIN

sql-statement ::= EXPLAIN sql-statement

EXPLAIN命令修飾語是一個非標準的擴展功能,靈感來自PostgreSQL中的相同命令,但操作完全不同。

若EXPLAIN關鍵字出現(xiàn)在任何SQLite的SQL命令之前,則SQLite庫返回不加EXPLAIN時執(zhí)行該命令所需要使用的虛擬機指令序列,而不是真正執(zhí)行該命令。關于虛擬機指令的更多信息參見系統(tǒng)結構描述或關于虛擬機的可用代碼

表達式

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

這一節(jié)與其它的各節(jié)有所不同。我們討論的不是一個單一的SQL命令,而是作為其他大部分命令的一部分的表達式。

SQLite支持如下的二元運算符,按優(yōu)先級由高至低排列:

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

所支持的一元運算符:

-     +     !     ~

注意等號和“不等”號的兩個變種。等號可以是 ===. “不等”號可以是!=<>. ||為“連接符”——它將兩個字符串連接起來。 %輸出左邊部分以右邊部分為模取模得到的余數(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ù)可以是如下幾種形式:

NNN   問號跟隨數(shù)字NNN為第NNN個參數(shù)占位。NNN需介于1和999之間。
  不加數(shù)字的問號為下一個參數(shù)占位。
:AAAA   冒號帶一個標識符名稱為一個名為AAAA的參數(shù)占位。命名的參數(shù)同樣可以使用序號占位,被賦予的參數(shù)序號為下一個尚未被使用的序號。建議不要混合使用命名代表的參數(shù)和序號代表的參數(shù)以免引起混淆。
$AAAA   $符號帶一個標識符名稱也可以為一個名為AAAA的參數(shù)占位。在這一情況下標識符名稱可以包括一個或更多的“::”以及包含任何文本的“(...)”后綴。該語法是Tcl編程語言中的一個可變形式。

不使用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ù)庫引擎中。

abs(X) 返回參數(shù)X的絕對值。
coalesce(X,Y,...) 返回第一個非空參數(shù)的副本。若所有的參數(shù)均為NULL,返回NULL。至少2個參數(shù)。
glob(X,Y) 用于實現(xiàn)SQLite的 "X GLOB Y"語法。可使用 sqlite3_create_function() 重載該函數(shù)從而改變GLOB運算符的功能。
ifnull(X,Y) 返回第一個非空參數(shù)的副本。 若兩個參數(shù)均為NULL,返回NULL。與上面的 coalesce()類似。
last_insert_rowid() 返回當前數(shù)據(jù)庫連接最后插入行的ROWID。sqlite_last_insert_rowid() API函數(shù)同樣可用于得到該值。
length(X) 返回X的長度,以字符計。如果SQLite被配置為支持UTF-8,則返回UTF-8字符數(shù)而不是字節(jié)數(shù)。
like(X,Y [,Z]) 用于實現(xiàn)SQL語法"X LIKE Y [ESCAPE Z]".若使用可選的ESCAPE子句,則函數(shù)被賦予三個參數(shù),否則只有兩個??墒褂?a href="http://localhost/Htmleditor.asp">sqlite3_create_function() 重載該函數(shù)從而改變LIKE運算符的功能。
lower(X) 返回X字符串的所有字符小寫化版本。這一轉換使用C語言庫的tolower()函數(shù),對UTF-8字符不能提供好的支持。
max(X,Y,...) 返回最大值。參數(shù)可以不僅僅為數(shù)字,可以為字符串。大小順序由常用的排序法則決定。注意,max()在有2個或更多參數(shù)時為簡單函數(shù),但當僅給出一個參數(shù)時它變?yōu)榫奂瘮?shù)。
min(X,Y,...) 返回最小值。與max()類似。
nullif(X,Y) 當兩參數(shù)不同時返回X,否則返回NULL.
quote(X) 返回參數(shù)的適于插入其它SQL語句中的值。字符串會被添加單引號,在內(nèi)部的引號前會加入逃逸符號。 BLOB被編碼為十六進制文本。當前的VACUUM使用這一函數(shù)實現(xiàn)。在使用觸發(fā)器實現(xiàn)撤銷/重做功能時這一函數(shù)也很有用。
random(*) 返回介于-2147483648和 +2147483647之間的隨機整數(shù)。
round(X)
round(X,Y)
X四舍五入,保留小數(shù)點后Y位。若忽略Y參數(shù),則默認其為0。
soundex(X) 計算字符串X的soundex編碼。參數(shù)為NULL時返回字符串“?000”。缺省的SQLite是不支持該函數(shù)的,當編譯時選項 -DSQLITE_SOUNDEX=1 時該函數(shù)才可用。
sqlite_version(*) 返回所運行的SQLite庫的版本號字符串。如 "2.8.0"。
substr(X,Y,Z) 返回輸入字符串X中以第Y個字符開始,Z個字符長的子串。X最左端的字符序號為1。若Y為負,則從右至左數(shù)起。若SQLite配置支持UTF-8,則“字符”代表的是UTF-8字符而非字節(jié)。
typeof(X) 返回表達式X的類型。返回值可能為“null”、“integer”、“real”、“text”以及“blob”。SQLite的類型處理參見SQLite3的數(shù)據(jù)類型。
upper(X) 返回X字符串的所有字符大寫化版本。這一轉換使用C語言庫的toupper()函數(shù),對UTF-8字符不能提供好的支持。

以下是缺省可用的聚集函數(shù)列表??梢允褂肅語言寫出其它的聚集函數(shù)然后使用sqlite3_create_function() API函數(shù)添加到數(shù)據(jù)庫引擎中。

在單參數(shù)聚集函數(shù)中,參數(shù)可以加前綴DISTINCT。這時重復參數(shù)會被過濾掉,然后才穿入到函數(shù)中。例如,函數(shù)“count(distinct X)”返回字段X的不重復非空值的個數(shù),而不是字段X的全部非空值。

avg(X) 返回一組中非空的X的平均值。非數(shù)字值作0處理。avg()的結果總是一個浮點數(shù),即使所有的輸入變量都是整數(shù)。

 

count(X)
count(*)
返回一組中X是非空值的次數(shù)的第一種形式。第二種形式(不帶參數(shù))返回該組中的行數(shù)。
max(X) 返回一組中的最大值。大小由常用排序法決定。
min(X) 返回一組中最小的非空值。大小由常用排序法決定。僅在所有值為空時返回NULL。
sum(X)
total(X)
返回一組中所有非空值的數(shù)字和。若沒有非空行,sum()返回NULL而total()返回0.0。NULL通常情況下并不是對于“沒有行”的和的一個有意義的結果,但SQL標準如此要求,且大部分其它SQL數(shù)據(jù)庫引擎這樣定義sum(),所以SQLite 也如此定義以保證兼容。我們提供非標準的total()函數(shù)作為解決該SQL語言設計問題的一個簡易方法。

total()的返回值式中為浮點數(shù)。sum()可以為整數(shù),當所有非空輸入均為整數(shù)時,和是精確的。若sum()的任意一個輸入既非整數(shù)也非NULL或計算中產(chǎn)生整數(shù)類型的溢出時,sum()返回接近真和的浮點數(shù)。

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”關鍵字,在已有表中插入一個新的行。若不定義字段列表,那么值的數(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子句

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

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。選項含義如下:

ROLLBACK

當發(fā)生約束沖突,立即ROLLBACK,即結束當前事務處理,命令中止并返回SQLITE_CONSTRAINT代碼。若當前無活動事務(除了每一條命令創(chuàng)建的默認事務以外),則該算法與ABORT相同。

ABORT

當發(fā)生約束沖突,命令收回已經(jīng)引起的改變并中止返回SQLITE_CONSTRAINT。但由于不執(zhí)行ROLLBACK,所以前面的命令產(chǎn)生的改變將予以保留。缺省采用這一行為。

FAIL

當發(fā)生約束沖突,命令中止返回SQLITE_CONSTRAINT。但遇到?jīng)_突之前的所有改變將被保留。例如,若一條UPDATE語句在100行遇到?jīng)_突100th,前99行的改變將被保留,而對100行或以后的改變將不會發(fā)生。

IGNORE

當發(fā)生約束沖突,發(fā)生沖突的行將不會被插入或改變。但命令將照常執(zhí)行。在沖突行之前或之后的行將被正常的插入和改變,且不返回錯誤信息。

REPLACE

當發(fā)生UNIQUE約束沖突,先存在的,導致沖突的行在更改或插入發(fā)生沖突的行之前被刪除。這樣,更改和插入總是被執(zhí)行。命令照常執(zhí)行且不返回錯誤信息。當發(fā)生NOT NULL約束沖突,導致沖突的NULL值會被字段缺省值取代。若字段無缺省值,執(zhí)行ABORT算法。

當沖突應對策略為滿足約束而刪除行時,它不會調(diào)用刪除觸發(fā)器。但在新版中這一特性可能被改變。

INSERT或UPDATE的OR子句定義的算法會覆蓋CREATE TABLE所定義的。ABORT算法將在沒有定義任何算法時缺省使用。

SQLite支持的編譯指令(Pragma)

PRAGMA命令是用于修改SQlite庫或查詢SQLite庫內(nèi)部數(shù)據(jù)(non-table)的特殊命令。PRAGMA 命令使用與其它SQLite命令(例如:SELECT、INSERT)相同的接口,但在如下重要方面與其它命令不同:

  • 在未來的SQLite版本中部分Pragma可能被刪除或添加,要小心使用。
  • 當使用未知的Pragma語句時不產(chǎn)生報錯。未知的Pragma僅僅會被忽略,即是說若是打錯了Pragma語句SQLite不會提示用戶。
  • 一些Pragma在SQL編譯階段生效而非執(zhí)行階段。即是說若使用C語言的sqlite3_compile()、sqlite3_step()、sqlite3_finalize() API(或類似的封裝接口中),Pragma可能在調(diào)用sqlite3_compile()期間起作用。
  • Pragma命令不與其它SQL引擎兼容。

可用的pragma命令有如下四個基本類型:


PRAGMA命令語法

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

使用整數(shù)值value的pragma也可以使用符號表示,字符串“on”、“true”和“yes”等同于1,“off”、“false”和“no”等同于0。這些字符串大小寫不敏感且無須進行引用。無法識別的字符串被當作1且不會報錯。value返回時是整數(shù)。


用于修改SQLite庫的操作的Pragma

  • PRAGMA auto_vacuum;
    PRAGMA auto_vacuum =
    0 | 1;

    查詢或設置數(shù)據(jù)庫的auto-vacuum標記。

    正常情況下,當提交一個從數(shù)據(jù)庫中刪除數(shù)據(jù)的事務時,數(shù)據(jù)庫文件不改變大小。未使用的文件頁被標記并在以后的添加操作中再次使用。這種情況下使用VACUUM命令釋放刪除得到的空間。

    當開啟auto-vacuum,當提交一個從數(shù)據(jù)庫中刪除數(shù)據(jù)的事務時,數(shù)據(jù)庫文件自動收縮,(VACUUM命令在auto-vacuum開啟的數(shù)據(jù)庫中不起作用)。數(shù)據(jù)庫會在內(nèi)部存儲一些信息以便支持這一功能,這使得數(shù)據(jù)庫文件比不開啟該選項時稍微大一些。

    只有在數(shù)據(jù)庫中未建任何表時才能改變auto-vacuum標記。試圖在已有表的情況下修改不會導致報錯。

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

    查詢或修改SQLite一次存儲在內(nèi)存中的數(shù)據(jù)庫文件頁數(shù)。每頁使用約1.5K內(nèi)存,缺省的緩存大小是2000。若需要使用改變大量多行的UPDATE或DELETE命令,并且不介意SQLite使用更多的內(nèi)存的話,可以增大緩存以提高性能。

    當使用cache_size pragma改變緩存大小時,改變僅對當前對話有效,當數(shù)據(jù)庫關閉重新打開時緩存大小恢復到缺省大小。要想永久改變緩存大小,使用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語句不返回數(shù)據(jù)。當開啟count-changes,以上語句返回一行含一個整數(shù)值的數(shù)據(jù)——該語句插入、修改或刪除的行數(shù)。返回的行數(shù)不包括由觸發(fā)器產(chǎn)生的插入、修改或刪除等改變的行數(shù)。

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

    查詢或修改SQLite一次存儲在內(nèi)存中的數(shù)據(jù)庫文件頁數(shù)。每頁使用約1.5K內(nèi)存,它與cache_size pragma類似,只是它永久性地改變緩存大小。利用該pragma,你可以設定一次緩存大小,并且每次重新打開數(shù)據(jù)庫時都繼續(xù)使用該值。

  • 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函數(shù)。正常情況下,empty-result-callbacks標記清空,則對返回0行數(shù)據(jù)的命令不調(diào)用sqlite3_exec()的回叫函數(shù),當設置了empty-result-callbacks,則調(diào)用回叫 函數(shù)一次,置第三個參數(shù)為0(NULL)。這使得使用sqlite3_exec() API的程序即使在一條查詢不返回數(shù)據(jù)時依然檢索字段名。

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

    在第一種形式中,若主數(shù)據(jù)庫已創(chuàng)建,這條pragma返回主數(shù)據(jù)庫使用得文本編碼格式,為“UTF-8”、“UTF-16le”(little-endian UTF-16 encoding)或者“UTF-16be”(big-endian UTF-16 encoding)中的一種。 若主數(shù)據(jù)庫未創(chuàng)建,返回值為當前會話創(chuàng)建的主數(shù)據(jù)庫將要使用的文本編碼格式。

    第二種及以后幾種形式只在主數(shù)據(jù)庫未創(chuàng)建時有效。這時該pragma設置當前會話創(chuàng)建的主數(shù)據(jù)庫將要使用的文本編碼格式?!癠TF-16”表示“使用本機字節(jié)順序的UTF-16編碼”。若這些形式在主數(shù)據(jù)庫創(chuàng)建后使用,將被忽略且不產(chǎn)生任何效果。

    數(shù)據(jù)庫的編碼格式設置后不能夠被改變。

    ATTACH命令創(chuàng)建的數(shù)據(jù)庫使用與主數(shù)據(jù)庫相同的編碼格式。

  • PRAGMA full_column_names;
    PRAGMA full_column_names =
    0 | 1;

    查詢或更改the full-column-names標記。該標記影響SQLite命名SELECT語句(當字段表達式為表-字段或通配符"*"時)返回的字段名的方式。正常情況下,當SELECT語句將兩個或多個表連接時,這類結果字段的返回名為,當SELECT語句查詢一個單獨的表時,返回字段名為。當設置了full-column-names標記,返回的字段名將統(tǒng)一為 不管是否對表進行了連接。

    若short-column-names和full-column-names標記同時被設置,則使用full-column-names方式。

  • PRAGMA fullfsync
    PRAGMA fullfsync =
    0 | 1;

    查詢或更改fullfsync標記。該標記決定是否在支持的系統(tǒng)上使用F_FULLFSYNC同步模式。缺省值為off。截至目前(2006-02-10)只有Mac OS X系統(tǒng)支持F_FULLFSYNC。

  • PRAGMA page_size;
    PRAGMA page_size =
    bytes;

    查詢或設置page-size值。只有在未創(chuàng)建數(shù)據(jù)庫時才能設置page-size。頁面大小必須是2的整數(shù)倍且大于等于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標記,返回的字段名將統(tǒng)一為不管是否對表進行了連接。

    若short-column-names和full-column-names標記同時被設置,則使用full-column-names方式。

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

    查詢或更改“synchronous”標記的設定。第一種形式(查詢)返回整數(shù)值。 當synchronous設置為FULL(2),SQLite數(shù)據(jù)庫引擎在緊急時刻會暫停以確定數(shù)據(jù)已經(jīng)寫入磁盤。這使系統(tǒng)崩潰或電源出問題時能確保數(shù)據(jù)庫在重起后不會損壞。FULL synchronous很安全但很慢。當synchronous設置為NORMAL,SQLite數(shù)據(jù)庫引擎在大部分緊急時刻會暫停,但不像FULL模式下那么頻繁。NORMAL模式下有很小的幾率(但不是不存在)發(fā)生電源故障導致數(shù)據(jù)庫損壞的情況。但實際上,在這種情況下很可能你的硬盤已經(jīng)不能使用,或者發(fā)生了其他的不可恢復的硬件錯誤。設置為synchronous OFF(0)時,SQLite在傳遞數(shù)據(jù)給系統(tǒng)以后直接繼續(xù)而不暫停。若運行SQLite的應用程序崩潰,數(shù)據(jù)不會損傷,但在系統(tǒng)崩潰或?qū)懭霐?shù)據(jù)時意外斷電的情況下數(shù)據(jù)庫可能會損壞。另一方面,在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”參數(shù)的設置。當temp_store設置為DEFAULT(0),使用編譯時的C預處理宏TEMP_STORE來定義儲存臨時表和臨時索引的位置。當設置為MEMORY(2)臨時表和索引存放于內(nèi)存中。當設置為FILE(1)則存放于文件中。temp_store_directory pragma可用于指定存放該文件的目錄。當改變temp_store設置,所有已存在的臨時表、索引、觸發(fā)器及視圖將被立即刪除。

    庫中的編譯時C預處理標志TEMP_STORE可以覆蓋該pragma設置。下面的表給出TEMP_STORE預處理宏和temp_store pragma交互作用的總結:

    TEMP_STOREPRAGMA
    temp_store
    臨時表和索引
    使用的存儲方式
    0 any 文件
    1 0 文件
    1 1 文件
    1 2 內(nèi)存
    2 0 內(nèi)存
    2 1 文件
    2 2 內(nèi)存
    3 any 內(nèi)存

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

    查詢或更改“temp_store_directory”設置——存儲臨時表和索引的文件所在的目錄。僅在當前連接有效,在建立新連接時重置為缺省值。

    當改變了temp_store_directory設置,所有已有的臨時表、索引、觸發(fā)器、視圖會被直接刪除。建議在數(shù)據(jù)庫一打開時就設置好temp_store_directory。

    directory-name需用單引號引起來。要想恢復缺省目錄,把directory-name設為空字符串。例如 PRAGMA temp_store_directory = ''。若directory-name未找到或不可寫會引發(fā)錯誤。

    臨時文件的缺省目錄與主機的系統(tǒng)有關,使用Unix/Linux/OSX系統(tǒng)的主機,缺省目錄是如下序列之中第一個可寫的/var/tmp、/usr/tmp、/tmp、current-directory。對于Windows NT,缺省目錄由Windows決定,一般為C:/Documents and Settings/user-name/Local Settings/Temp/。SQLite創(chuàng)建的臨時文件在使用完畢時就被unlink,所以操作系統(tǒng)可以在SQLite進程進行中自動刪除臨時文件。于是,正常情況下不能通過lsdir命令看到臨時文件。


用于查詢數(shù)據(jù)庫的schema的Pragma

  • PRAGMA database_list;

    對每個打開的數(shù)據(jù)庫,使用該數(shù)據(jù)庫的信息調(diào)用一次回叫函數(shù)。使用包括附加的數(shù)據(jù)庫名和索引名在內(nèi)的參數(shù)。第一行用于主數(shù)據(jù)庫,第二行用于存放臨時表的臨時數(shù)據(jù)庫。

  • PRAGMA foreign_key_list(table-name);

    對于參數(shù)表中每個涉及到字段的外鍵,使用該外鍵的信息調(diào)用一次回叫函數(shù)。每個外鍵中的每個字段都將調(diào)用一次回叫函數(shù)。

  • PRAGMA index_info(index-name);

    對該索引涉及到的每個字段,使用字段信息(字段名、字段號)調(diào)用一次回叫函數(shù)。

  • PRAGMA index_list(table-name);

    對表中的每個索引,使用索引信息調(diào)用回叫函數(shù)。參數(shù)包括索引名和一個指示索引是否唯一的標志。

  • PRAGMA table_info(table-name);

    對于表中的每個字段,使用字段信息(字段名、數(shù)據(jù)類型、可否為空、缺省值)調(diào)用回叫函數(shù)。


用于查詢/更改版本信息的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位有符號整數(shù),存放于數(shù)據(jù)庫頭中。

    schema-version通常只由SQLite內(nèi)部操作。每當數(shù)據(jù)庫的Schema改變時(創(chuàng)建或撤消表或索引),SQLite將這個值增大。Schema版本在每一次Query被執(zhí)行時被SQLite所使用,以確定編譯SQL Query時內(nèi)部Cache的Schema與編譯后的Query實際執(zhí)行時數(shù)據(jù)庫的Schema相匹配。使用“PRAGMA schema_version”更改schema-version會破壞這一機制,有導致程序崩潰或數(shù)據(jù)庫損壞的潛在危險。請小心使用!

    user-version不在SQLite內(nèi)部使用,任何程序可以用它來做任何事。


用于庫Debug的Pragma

  • PRAGMA integrity_check;

    該命令對整個數(shù)據(jù)庫進行完整性檢查,查找次序顛倒的記錄,丟失的頁,殘缺的記錄以及損壞的索引。若發(fā)現(xiàn)任何問題則返回一形容問題所在的字符串,若一切正常返回“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庫中的虛擬數(shù)據(jù)庫引擎追蹤,用于Debug。更多信息,查看 VDBE文檔。

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

    打開或關閉虛擬機程序列表,當開啟列表功能,整個程序的內(nèi)容在執(zhí)行前被打印出來,就像在每條語句之前自動執(zhí)行EXPLAIN。語句在打印列表之后正常執(zhí)行。用于Debug。更多信息,查看VDBE文檔。

REINDEX

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

REINDEX命令用于刪除并從草稿重建索引。當比較順序改變時該命令顯得很有效。

在第一種形式中,所有附加數(shù)據(jù)庫中使用該比較順序的索引均被重建。在第二種形式中,[database-name.]table/index-name標識出一個表,所有關聯(lián)該表的索引被重建。若標識出索引,則僅僅該索引被刪除并重建。

若不指定database-name而指定表/索引名以及比較順序,只有關聯(lián)該比較順序的索引被重建。在重建索引時總是指定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語句用于查詢數(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

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

UPDATE語句用于改變表中所選行的字段值。每個UPDATE的賦值的等號左邊為字段名而右邊為任意表達式。表達式可以使用其它字段的值。所有的表達式將在賦值之前求出結果??梢允褂肳HERE子句限定需要改變的行。

在使用這一命令時,利用可選的ON CONFLICT子句可以定義替代的約束沖突判定算法。更多信息,參見ON CONFLICT。

VACUUM

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

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開啟該模式。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多