00-SQLite的SQL語法

来源:http://www.cnblogs.com/wohenben/archive/2016/04/15/5394590.html
-Advertisement-
Play Games

SQLite的SQL語法 SQLite的SQL語法 SQLite庫可以解析大部分標準SQL語言。但它也省去了一些特性並且加入了一些自己的新特性。這篇文檔就是試圖描述那些SQLite支持/不支持的SQL語法的。查看關鍵字列表。 如下語法表格中,純文本用藍色粗體顯示。非終極符號為斜體紅色。作為語法一部分 ...


 

SQLite的SQL語法

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

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

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

SQLite執行如下的語法:

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。這一命令不能用於在附加資料庫之間移動表,只能在同一個資料庫中對錶進行重命名。

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

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 FROMfilename
[ 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_mastersqlite_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 ASselect-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 ASselect-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 .]
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 --SQLSERVER資料庫表各種同步技術 減少SQLServer中每次的同步數據量 2 3 --說到資料庫,我就不由地想到同步數據,如何儘可能地減少每次的同步數據量,以此來提高同步效率,降低對網路帶寬的消耗是我們使用者所關心的。對於大批量的數據同步,這一點是應引起重視的。獲取差異數據是解決這個 ...
  • 前2天下載了一個2016的rc版本來玩一下,首先感覺是~開發者版本免費啦!!撒花!!!另外一個東西,sql server 2016能支持json 的解析和應用啦,雖然我不知道它的性能如何,先來一發測試一下功能 測試一下基本的,從查詢結果裡面構造一個json 的格式 這個是預設模式下麵使用json的查 ...
  • 1、in和exists in是把外表和內表作hash(字典集合)連接,而exists是對外表作迴圈,每次迴圈再對內表進行查詢。一直以來認為exists比in效率高的說法是不准確的,如果查詢的兩個表大小相當,那麼用in和exists差別不大;如果兩個表中一個較小一個較大,則子查詢表大的用exists, ...
  • ...
  • 1、定義游標:列出每個員工的姓名、部門名稱並編程顯示第10個到第20個記錄。 2、定義游標:從雇員表中顯示工資大於3000的記錄,只要姓名、部門編號和工資。編程顯示其中的奇數記錄。 3、計算下麵級數當末項小於0.001時的部分和。 1/(1*2)+1/(2*3)+1/(3*4)+…+1/(n*(n+ ...
  • 癥狀:前一天在MySQL中刪除了幾個不用的資料庫後登陸MySQL出現以下錯誤: mysql -u root -p passwd ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysql ...
  • 轉載: http://www.cnblogs.com/stephen-liu74/archive/2012/03/09/2328757.html http://www.runoob.com/sqlite/sqlite-tutorial.html ...
  • 資料庫系統的 三級模式結構 資料庫系統是由外模式,模式和內模式三級構成 1.模式(schema) 模式也稱邏輯模式,是資料庫中全體數據的邏輯結構和特征的描述,是所有用戶的公共數據視圖。 2.外模式(external schema) 外模式也稱子模式(subschema)或用戶模式,它是資料庫用戶(包 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...