先來一段客套話
SQLite,是一款輕型的數據庫,是遵守ACID的關聯式數據庫管理系統,它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠支持Windows/Linux/Unix等等主流的操作系統,同時能夠跟很多程序語言相結合,比如 Tcl、C#、PHP、Java等,還有ODBC接口,同樣比起Mysql、PostgreSQL這兩款開源世界著名的數據庫管理系統來講,它的處理速度比他們都快。SQLite第一個Alpha版本誕生於2000年5月。 至今已經有12個年頭,SQLite也迎來了一個版本 SQLite 3已經發布。

它的Logo里頭的那條毛,估計就是說明它夠輕的意思。
1 工具
最原始的工具當然是命令模式的工具,也有圖形界面的,FireFox的SQLite Manager,SQLiteSpy,VS也行,以前找到一個免費的好像還可以的忘了叫什么名字了。找了幾個都不好用干脆原始一點用命令模式算了,可以到官網里下,有個Shell的那個就是命令行工具了。
輸入“.help”就會彈出一大堆內置的命令,各個命令的功能如下
| 命令名 |
命令說明 |
| .help |
列出所有內置命令。 |
| .backup DBNAME FILE |
備份指定的數據庫到指定的文件,缺省為當前連接的main數據庫。 |
| .databases |
列出當前連接中所有attached數據庫名和文件名。 |
| .dump TABLENAME ... |
以SQL文本的格式DUMP當前連接的main數據庫,如果指定了表名,則只是DUMP和表名匹配的數據表。參數TABLENAME支持LIKE表達式支持的通配符。 |
| .echo ON|OFF |
打開或關閉顯示輸出。 |
| .exit |
退出當前程序。 |
| .explain ON|OFF |
打開或關閉當前連接的SELECT輸出到Human Readable形式。 |
| .header(s) ON|OFF |
在顯示SELECT結果時,是否顯示列的標題。 |
| .import FILE TABLE |
導入指定文件的數據到指定表。 |
| .indices TABLENAME |
顯示所有索引的名字,如果指定表名,則僅僅顯示匹配該表名的數據表的索引,參數TABLENAME支持LIKE表達式支持的通配符。 |
| .log FILE|off |
打開或關閉日志功能,FILE可以為標准輸出stdout,或標准錯誤輸出stderr。 |
| .mode MODE TABLENAME |
設置輸出模式,這里最為常用的模式是column模式,使SELECT輸出列左對齊顯示。其他模式有csv,html,inser,line,list,tabs,tcl |
| .nullvalue STRING |
使用指定的字符串代替NULL值的顯示。 |
| .output FILENAME |
將當前命令的所有輸出重定向到指定的文件。 |
| .output stdout |
將當前命令的所有輸出重定向到標准輸出(屏幕)。 |
| .quit |
退出當前程序。 |
| .read FILENAME |
執行指定文件內的SQL語句。 |
| .restore DBNAME FILE |
從指定的文件還原數據庫,缺省為main數據庫,此時也可以指定其它數據庫名,被指定的數據庫成為當前連接的attached數據庫。 |
| .schema TABLENAME |
顯示數據表的創建語句,如果指定表名,則僅僅顯示匹配該表名的數據表創建語句,參數TABLENAME支持LIKE表達式支持的通配符。 |
| .separator STRING |
改變輸出模式和.import的字段間分隔符。 |
| .show |
顯示各種設置的當前值。 |
| .tables TABLENAME |
列出當前連接中main數據庫的所有表名,如果指定表名,則僅僅顯示匹配該表名的數據表名稱,參數TABLENAME支持LIKE表達式支持的通配符。 |
| .width NUM1 NUM2 ... |
在MODE為column時,設置各個字段的寬度,注意:該命令的參數順序表示字段輸出的順序。 |
| .stats ON|OFF |
開啟或關閉統計表。 |
| .timeout MS |
嘗試已MS毫秒開啟鎖了的表 |
| .trace FILE|off |
在沒個表達式運行時輸出它 |
| .vfsname AUX |
打印VFS堆棧的名稱 |
| .timer ON|OFF |
開啟或關閉CPU的計時測量 |
如果在cmd處開啟SQLite的話 用以下命令
sqlite ‘DB file fullname’
如果直接打開SQLite3.exe的話,要打開某個數據庫,則是用添加某個數據到當前連接的形式
ATTACH DATABASE ‘DB file fullname’ AS DB name;
這句注意后面有個分號,同樣兩句的文件名都不能有中文,否則會出現打不開的錯誤。
2 數據類型
秉承了學習程序語言的習慣,熟悉了環境之后就了解數據類型了。
SQLite的數據類型實質上只有五種,
NULL:只有一個值,就是NULL
INTEGER:無符號整形。
REAL:浮點數。
TEXT:字符串。
BLOB:Blob數據。
這里要額外說明一下,SQLite采用的是動態數據類型,這一點與其他類型的數據庫不同,其他類型的數據庫是在定義字段時設定了字段的數據類型,以后該字段只能存放設定類型的數據,而SQLite則不然,比如定義了一個INTEGER類型的字段col1,也可以正常地往該字段存放一串字符串:”ABCDEFGI…..”。不過若要考慮到要把庫轉移到別的數據庫中,那還是中規中矩地填上相應類型的數據好一點。
只有這五種數據類型給我的第一感覺是不夠用,其實已經夠用了。因為SQLite有個親緣性的概念。當數據插入時,該字段的數據將會優先采用親緣類型作為該值的存儲方式,除非親緣類型不匹配或無法轉換當前數據到該親緣類型,這樣SQLite才會考慮其它更適合該值的類型存儲該值。親緣類型有一下五種
- TEXT
- NUMBERIC
- INTEGER
- REAL
- NONE
親緣性類型轉換有以下規則
- 如果類型字符串中包含"INT",那么該字段的親緣類型是INTEGER。
- 如果類型字符串中包含"CHAR"、"CLOB"或"TEXT",那么該字段的親緣類型是TEXT,如VARCHAR。
- 如果類型字符串中包含"BLOB",那么該字段的親緣類型是NONE。
- 如果類型字符串中包含"REAL"、"FLOA"或"DOUB",那么該字段的親緣類型是REAL。
- 其余情況下,字段的親緣類型為NUMERIC。
各種聲明類型及親緣類型關系如下表
| 表的字段類型或者轉換的類型 |
親緣類型 |
使用的規則 |
| INT |
INTEGER |
1 |
| CHARACTER(20) |
TEXT |
2 |
| BLOB |
NONE |
3 |
| REAL |
REAL |
4 |
| NUMERIC |
NUMERIC |
5 |
另外提一下就是自增列,在別的數據庫里都有一個自增列,在SQLite里如果要設置一列為自增列時,則需要把它的類型設為INTEGER而且把它作為主鍵。
3 運算符
3.1運算符介紹
SQLite支持以下二元運算符,下面則是從最高到最低的優先級排序
||
* / %
+ -
<< >> & |
< <= > >=
= == != <> IS IS NOT IN LIKE GLOB MATCH REGEXP
AND
OR
支持的一元運算符有
- + ~ NOT
注意一下,上提到的二元運算符中,|| 是用於字符串的連接,不是 + ,如果要連接兩個字符串”Hello”和”World”
SELECT “Hello”+”World” --結果是0.0 SELECT “Hello”||”World” --結果是”HelloWorld”
GLOB運算符與LIKE類似,不過GLOB是區分大小寫的
MATCH運算符用在全文檢索中。例如這兩句
SELECT title, body FROM pages WHERE pages MATCH 'world'; SELECT title, body FROM pages WHERE title MATCH 'world';
這兩句,前一個 MATCH 左邊寫了表名,后一個寫的是列名。后一個僅搜索 title 列,前一個是搜索全部列(docid 列以外)。
MATCH 右側的表達式支持模糊查詢、支持指定列查詢、支持 AND/OR/NEAR/NOT 等運算,例如
SELECT title, body FROM pages WHERE pages MATCH 'hel*'; SELECT title, body FROM pages WHERE pages MATCH 'title:hello'; SELECT title, body FROM pages WHERE pages MATCH 'hello AND world'; SELECT title, body FROM pages WHERE pages MATCH '(hello NEAR world) OR (program AND language)';
但要注意只能出現一次 MATCH 判斷,WHERE title MATCH 'hello' AND body MATCH 'world' 是不行的,可以改作 WHERE pages MATCH 'title:hello AND body:world'。
REGEXP運算符是用戶函數regexp()的一個特殊的代表符號。缺省情況下regexp()函數不被定義,所以使用REGEXP運算符會報錯。當運行時存在用戶定義的“regexp”函數的定義,則調用該函數以實現REGEXP運算符功能。
3.2 比較運算符的規則
上面提到一些比較運算符,它有以下規則
- 存儲方式為NULL的數值小於其它存儲類型的值。
- 存儲方式為INTEGER和REAL的數值小於TEXT或BLOB類型的值,如果同為INTEGER或REAL,則基於數值規則進行比較。
- 存儲方式為TEXT的數值小於BLOB類型的值,如果同為TEXT,則基於文本規則(ASCII值)進行比較。
- 如果是兩個BLOB類型的數值進行比較,其結果為C運行時函數memcmp()的結果。
4 表達式
4.1 條件表達式
該表達式的語法規則如下:
1). CASE x WHEN w1 THEN r1 WHEN w2 THEN r2 ELSE r3 END
2). CASE WHEN x=w1 THEN r1 WHEN x=w2 THEN r2 ELSE r3 END
4.2 轉換表達式
該表達式的語法規則如下:
CAST(expr AS target_type)
目標類型則是TEXT,REAL,INTEGER,NUMBERIC這四種親緣類型的其中之一,規則如下
| 目標類型 |
轉換規則描述 |
| TEXT |
如果轉換INTEGER或REAL類型的值到TEXT類型直接轉換即可,就像C/C++接口函數sqlite3_snprintf所完成的工作。 |
| REAL |
如果轉換TEXT類型的值到REAL類型,在該文本的最前部,將可以轉換為實數的文本轉換為相應的實數,其余部分忽略。其中該文本值的前導零亦將被全部忽略。如果該文本值沒有任何字符可以轉換為實數,CAST表達式的轉換結果為0.0。 |
| INTEGER |
如果轉換TEXT類型的值到INTEGER類型,在該文本的最前部,將可以轉換為整數的文本轉換為相應的整數,其余部分忽略。其中該文本值的前導零亦將被全部忽略。如果該文本值沒有任何字符可以轉換為整數,CAST表達式的轉換結果為0。 |
| NUMERIC |
如果轉換文本值到NUMERIC類型,則先將該值強制轉換為REAL類型,只有在將REAL轉換為INTEGER不會導致數據信息丟失以及完全可逆的情況下,SQLite才會進一步將其轉換為INTEGER類型。 |
如果expr是NULL那么結果也是NULL
5 函數
5.1聚合函數
SQLite中支持的聚合函數在很多其他數據庫中也同樣支持,這里還需要進一步說明的是,對於所有聚合函數而言,distinct關鍵字可以作為函數參數字段的前置屬性,以便在進行計算時忽略到所有重復的字段值,如count(distinct x)。
| 函數 |
說明 |
| avg(x) |
該函數返回在同一組內參數字段的平均值。對於不能轉換為數字值的String和BLOB類型的字段值,如'HELLO',SQLite會將其視為0。avg函數的結果總是浮點型,唯一的例外是所有的字段值均為NULL,那樣該函數的結果也為NULL。 |
| count(x|*) |
count(x)函數返回在同一組內,x字段中值不等於NULL的行數。count(*)函數返回在同一組內的數據行數。 |
| group_concat(x[,y]) |
該函數返回一個字符串,該字符串將會連接所有非NULL的x值。該函數的y參數將作為每個x值之間的分隔符,如果在調用時忽略該參數,在連接時將使用缺省分隔符","。再有就是各個字符串之間的連接順序是不確定的。 |
| max(x) |
該函數返回同一組內的x字段的最大值,如果該字段的所有值均為NULL,該函數也返回NULL。 |
| min(x) |
該函數返回同一組內的x字段的最小值,如果該字段的所有值均為NULL,該函數也返回NULL。 |
| sum(x) |
該函數返回同一組內的x字段值的總和,如果字段值均為NULL,該函數也返回NULL。如果所有的x字段值均為整型或者NULL,該函數返回整型值,否則就返回浮點型數值。最后需要指出的是,如果所有的數據值均為整型,一旦結果超過上限時將會拋出"integer overflow"的異常。 |
| total(x) |
該函數不屬於標准SQL,其功能和sum基本相同,只是計算結果比sum更為合理。比如當所有字段值均為NULL時,和sum不同的是,該函數返回0.0。再有就是該函數始終返回浮點型數值。該函數始終都不會拋出異常。 |
5.2 內置函數
此外SQLite中還有一些內置函數,如下表
| 函數 |
說明 |
| abs(X) |
該函數返回數值參數X的絕對值,如果X為NULL,則返回NULL,如果X為不能轉換成數值的字符串,則返回0,如果X值超出Integer的上限,則拋出"Integer Overflow"的異常。 |
| changes() |
該函數返回最近執行的INSERT、UPDATE和DELETE語句所影響的數據行數。我們也可以通過執行C/C++函數sqlite3_changes()得到相同的結果。 |
| coalesce(X,Y,...) |
返回函數參數中第一個非NULL的參數,如果參數都是NULL,則返回NULL。該函數至少2個參數。 |
| ifnull(X,Y) |
該函數等同於兩個參數的coalesce()函數,即返回第一個不為NULL的函數參數,如果兩個均為NULL,則返回NULL。 |
| length(X) |
如果參數X為字符串,則返回字符的數量,如果為數值,則返回該參數的字符串表示形式的長度,如果為NULL,則返回NULL。 |
| lower(X) |
返回函數參數X的小寫形式,缺省情況下,該函數只能應用於ASCII字符。 |
| ltrim(X[,Y]) |
如果沒有可選參數Y,該函數將移除參數X左側的所有空格符。如果有參數Y,則移除X左側的任意在Y中出現的字符。最后返回移除后的字符串。 |
| max(X,Y,...) |
返回函數參數中的最大值,如果有任何一個參數為NULL,則返回NULL。 |
| min(X,Y,...) |
返回函數參數中的最小值,如果有任何一個參數為NULL,則返回NULL。 |
| nullif(X,Y) |
如果函數參數相同,返回NULL,否則返回第一個參數。 |
| random() |
返回整型的偽隨機數。 |
| replace(X,Y,Z) |
將字符串類型的函數參數X中所有子字符串Y替換為字符串Z,最后返回替換后的字符串,源字符串X保持不變。 |
| round(X[,Y]) |
返回數值參數X被四舍五入到Y刻度的值,如果參數Y不存在,缺省參數值為0。 |
| rtrim(X[,Y]) |
如果沒有可選參數Y,該函數將移除參數X右側的所有空格符。如果有參數Y,則移除X右側的任意在Y中出現的字符。最后返回移除后的字符串。 |
| substr(X,Y[,Z]) |
返回函數參數X的子字符串,從第Y位開始(X中的第一個字符位置為1)截取Z長度的字符,如果忽略Z參數,則取第Y個字符后面的所有字符。如果Z的值為負數,則從第Y位開始,向左截取abs(Z)個字符。如果Y值為負數,則從X字符串的尾部開始計數到第abs(Y)的位置開始。 |
| total_changes() |
該函數返回自從該連接被打開時起,INSERT、UPDATE和DELETE語句總共影響的行數。我們也可以通過C/C++接口函數sqlite3_total_changes()得到相同的結果。 |
| trim(x[,y]) |
如果沒有可選參數Y,該函數將移除參數X兩側的所有空格符。如果有參數Y,則移除X兩側的任意在Y中出現的字符。最后返回移除后的字符串。 |
| upper(X) |
返回函數參數X的大寫形式,缺省情況下,該函數只能應用於ASCII字符。 |
| typeof(X) |
返回函數參數數據類型的字符串表示形式,如"Integer、text、real、null"等。 |
5.3 日期和時間函數
SQLite支持以下五種日期時間函數
date(timestring, modifier, modifier, ...)
time(timestring, modifier, modifier, ...)
datetime(timestring, modifier, modifier, ...)
julianday(timestring, modifier, modifier, ...)
strftime(format, timestring, modifier, modifier, ...)
以上五種函數中timestring的格式如下所示
- YYYY-MM-DD
- YYYY-MM-DD HH:MM
- YYYY-MM-DD HH:MM:SS
- YYYY-MM-DD HH:MM:SS.SSS
- YYYY-MM-DDTHH:MM
- YYYY-MM-DDTHH:MM:SS
- YYYY-MM-DDTHH:MM:SS.SSS
- HH:MM
- HH:MM:SS
- HH:MM:SS.SSS
- now
- DDDDDDDDDD
格式5~7中,那個加粗的“T”是按照ISO-8061標准分割日期和時間的分隔符,格式7~8中只有時間部分,日期部分全都默認設為2000-01-01,格式11的now是指當前UTC時間,格式12是用於julianday的。
Modifier修改符如下所示
- NNN days
- NNN hours
- NNN minutes
- NNN.NNNN seconds
- NNN months
- NNN years
- start of month
- start of year
- start of day
- weekday N
- unixepoch
- localtime
- utc
修改符unixepoc只用於DDDDDDDDDD格式的timestring后面,它會使得DDDDDDDDDD解釋成非一般性的儒略日,而是一個時間戳——從1970年始的秒數。
修改符localtime是假定它左邊的時間是UTC的情況下把它調整成當地時間。
修改符utc則與localtime相反,它是把左邊的時間當左當地時間並把它轉換成UTC。
上面的字母”N”是指加減的日期或時間值,正則加,負則減。修改符的順序極為重要,SQLite將會按照從左到右的順序依次執行修改符。
strftime函數的格式信息
| 格式 |
說明 |
| %d |
day of month: 00 |
| %f |
fractional seconds: SS.SSS |
| %H |
hour: 00-24 |
| %j |
day of year: 001-366 |
| %J |
Julian day number |
| %m |
month: 01-12 |
| %M |
minute: 00-59 |
| %s |
seconds since 1970-01-01 |
| %S |
seconds: 00-59 |
| %w |
day of week 0-6 with Sunday==0 |
| %W |
week of year: 00-53 |
| %Y |
year: 0000-9999 |
| %% |
% |
其余四個函數等價的strftime如下
date(...) strftime('%Y-%m-%d', ...)
time(...) strftime('%H:%M:%S', ...)
datetime(...) strftime('%Y-%m-%d %H:%M:%S', ...)
julianday(...) strftime('%J', ...)
date函數的缺省格式為:"YYYY-MM-DD",time函數的缺省格式為:"HH:MM:SS",datetime函數的缺省格式為:"YYYY-MM-DD HH:MM:SS"。Julianday函數的缺省格式為公元前4714年11月24日格林威治正午起經過的天數。
6 SQL
有關SQLite的SQL語句,提一下就是它的分頁查詢,與MySQL的一樣方便,用一個Limit
SELECT * FROM tableName Limit number1,number2
number1是起始的rowid,number2是自number1始讀的行數。
此外還列出兩條SQL語句,分別是查庫里的表名和表里頭字段的信息
select name from sqlite_master where type='table'; PRAGMA table_info([tablename])
7 連接到.NET
最后到介紹.NET的程序連接SQLite了。
要引用的dll文件可以從官網上下載,它的使用方式跟連SQL Server的一樣,也是Connection,Command,DataReader這些類。連接字符串最簡單的形式是這樣
Data Source=db file fullname;
有關連接字符串的其他參數,如下表所示:
| Parameter |
Values |
Required |
Default |
| Data Source |
This may be a file name, the string ":memory:", or any supported URI (starting with SQLite 3.7.7). |
Y |
|
| Version |
3 |
N |
3 |
| UseUTF16Encoding |
True |
N |
False |
| DateTimeFormat |
Ticks - Use the value of DateTime.Ticks. |
N |
ISO8601 |
| DateTimeKind |
Unspecified - Not specified as either UTC or local time. |
N |
Unspecified |
| BaseSchemaName |
Some base data classes in the framework (e.g. those that build SQL queries dynamically) assume that an ADO.NET provider cannot support an alternate catalog (i.e. database) without supporting alternate schemas as well; however, SQLite does not fit into this model. Therefore, this value is used as a placeholder and removed prior to preparing any SQL statements that may contain it. |
N |
sqlite_default_schema |
| BinaryGUID |
True - Store GUID columns in binary form |
N |
True |
| Cache Size |
{size in bytes} |
N |
2000 |
| Synchronous |
Normal - Normal file flushing behavior |
N |
Full |
| Page Size |
{size in bytes} |
N |
1024 |
| Password |
{password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. |
N |
|
| Enlist |
Y - Automatically enlist in distributed transactions |
N |
Y |
| Pooling |
True - Use connection pooling |
N |
False |
| FailIfMissing |
True - Don't create the database if it does not exist, throw an error instead |
N |
False |
| Max Page Count |
{size in pages} - Limits the maximum number of pages (limits the size) of the database |
N |
0 |
| Legacy Format |
True - Use the more compatible legacy 3.x database format |
N |
False |
| Default Timeout |
{time in seconds} |
N |
30 |
| Journal Mode |
Delete - Delete the journal file after a commit |
N |
Delete |
| Read Only |
True - Open the database for read only access |
N |
False |
| Max Pool Size |
The maximum number of connections for the given connection string that can be in the connection pool |
N |
100 |
| Default IsolationLevel |
The default transaciton isolation level |
N |
Serializable |
| Foreign Keys |
Enable foreign key constraints |
N |
False |
| Flags |
Extra behavioral flags for the connection. See the SQLiteConnectionFlags enumeration for possible values. |
N |
Default |
| SetDefaults |
True - Apply the default connection settings to the opened database. |
N |
True |
| ToFullPath |
True - Attempt to expand the data source file name to a fully qualified path before opening. |
N |
True |
其實這篇有一部分摘自 Stephen_Liu 的SQLite學習手冊,望其有怪莫怪。文中如果有什么說錯的說漏的還請各位大俠批評指正。最后用一個連接結束這篇博文SQLiteHelper
