C# SQLite 数据库操作语句与文件视图管理器
//sqlite數據庫視圖管理器
SQLiteSpy是一款專業的SQLite數據庫管理,主要用于讀取sqlite數據庫,建立新的SQL查詢,視圖,復制和刪除表、編輯單元格,以及查看索引,觸發器和排序規則。從而讓用戶更容易探討、分析和操縱sqlite3的數據庫。
SQLiteSpy不會對系統性能造成壓力,因為它運行在非常少的CPU和RAM上。它具有良好的響應時間和工作正常,而不會導致操作系統掛起,崩潰或彈出錯誤對話框。總而言之,SQLiteSpy提供了一個查看和執行SQL查詢的簡單解決方案。
SQLiteSpy中文版功能
1、數據庫一覽:
樹狀顯示所有的架構,包括表,列,索引和觸發器在數據庫中包含的項目,按F5更新架構樹,雙擊一個表或視圖來顯示它的數據,使用常用的命令的上下文菜單
2、網格單元格編輯:
表格單元格中編輯,顯示一個表通過樹狀架構,選擇一個單元格,然后按F2鍵調用編輯器,然后修改并確認您的更改寫回到表里
3、數據類型顯示:
本機的SQL數據類型顯示不同的背景顏色來幫助檢測類型錯誤,類型錯誤可能會導致性能下降或錯誤的SELECT結果集,防止NULL值與空字符串混淆
4、完全的Unicode:
SQLiteSpy具有完全支持SQLite的Unicode的能力,數據顯示和輸入是完全實現為Unicode,包括SQL命令
5、多個SQL編輯:
現代標簽是用來編輯和顯示的查詢語句和結果比較容易多個SQL查詢,SQL查詢執行輸入或加載到SQL他們編輯,然后按F9鍵運行該查詢,或Ctrl + F9來運行當前行或選擇值
6、時間測量:
SQL執行的時間會自動測量和顯示,以幫助優化查詢
7、正則表達式:
在SQL關鍵字regexp是支持,并增加了完整的Perl的正則表達式語法5.10 SQLiteSpy的實施,實現了利用DIRegEx庫
8、數學SQL函數:
下面的SQL函數可用數學除了SQLite的默認:ACOS(), ASIN(), ATAN(), ATAN(), ATAN2(), CEIL(), CEILING(), COS(), COT(), DEGREES(), EXP(), FLOOR(), LN(), LOG(), LOG(), LOG2(), LOG10(), MOD(), PI(), POW(), RADIANS(), SIGN(), SIN(), SQRT(), TAN(), TRUNCATE()
9、數據壓縮:
壓縮的SQL函數()適用的zlib的緊縮到任何文本或BLOB值
10、緊湊型結果儲存:
使用內部數據存儲機制,以達到最佳的兼容SQLite的原生數據類型,因此,SQLiteSpy使用遠低于其它的SQLite管理內存和更有效地處理大量的表
11、內建的SQLite引擎:
SQLiteSpy已建成一個單一的應用程序文件與SQLite數據庫引擎可執行文件,不需要部署任何DLL文件,這使得SQLiteSpy更易于部署
12、加密支持:
SQLiteSpy可以閱讀和修改加密的數據庫文件由DISQLite3產生,DISQLite3實現了自己的母語AES加密,這為不符合商業SQLite的加密擴展(SSE)的或任何其他第三方的實施提供兼容
13、易安裝和卸載:
要運行SQLiteSpy,只需解壓SQLiteSpy.exe文件到任何目錄和執行文件,不需要安裝,剛開始時,該程序創建一個文件SQLiteSpy.db3(1 sqlite3的數據庫)來存儲的和設置,它不寫任何其他文件或注冊表;
卸載一樣只是簡單的刪除兩個文件:應用程序的可執行文件和數據庫文件即可
更新日志
SQLiteSpy v1.9.11更新
1、升級內置DISQLite3引擎到SQLite 3.13.0
2、新增JSON(基于JavaScript語言的輕量級數據交換格式)擴展選項
例如:SELECT json_extract('{“a”:2,“c”:[4,5,{“f”:7}]}', '$.c[2].f');
3、新增Session擴展
例如:SELECT * FROM generate_series(0,100,5);
?
//sqlite語句設計
?
C# SQLite?數據庫操作學習
運行環境:Window7 64bit,.NetFramework4.61,C# 7.0
參考:
- SQLite 官網
- SQL As Understood By SQLite
- System.Data.SQLite
- 菜鳥教程
- SQL 教程
章節:
- 1、下載安裝
- 2、數據類型
- 3、創建數據庫
- 4、刪除數據庫
- 5、創建表
- 6、刪除表
- 7、查詢表結構
- 8、更改表名
- 9、增加列(字段)
- 10、讀取創建表的 SQL 語句
- 11、更改列名
- 12、刪除列
- 13、插入數據
- 14、替換數據
- 15、更新數據
- 16、刪除數據
- 17、查詢數據
- 18、獲取查詢數據的行數(多少條記錄)
- 19、事務 Transaction
- 20、整理數據庫
正文:
一、下載安裝
這段時間在學習 C# 編程中,想寫一個簡單的進銷存程序,就想到了用數據庫,需要一個簡單便攜的桌面數據庫,想自己寫個,功力太淺,可以做為以后練手學習的項目。原來會用的 Foxpro 已經被微軟不知丟在哪個旮旯了,在網上找了一下,發現只有 Access 和 Sqlite 可選,看了很多對比,決定還是學習使用 Sqlite。
在?System.Data.SQLite 官網的 download 中的 Setups for 64-bit Windows (.NET Framework 4.6)?sqlite-netFx46-setup-x64-2015-1.0.104.0.exe (17.99 MiB)?下載然后運行安裝。
更簡單的做法是在 Visual Studio 2017 的 NuGet 中,輸入:install-package system.data.sqlite.x64。
sqlite數據庫的可視化工具中,?SqliteExpert?不錯,下載?SQLite Expert Personal 4.x?。
工具備齊了,由于知道上面這個System data Sqlite 是用 C# 封裝好的,下來我們打開Visual Studio 2017,新開個工程,在菜單“項目”→“添加引用”→“瀏覽”?中,去 Sqlite 的安裝目錄下選擇 System.Data.SQLite.dll,才305k的鏈接庫。引用了后,在VS右上角的“解決方案資源管理器”中看看引用下的 System.Data.SQlite 的引用屬性中的“復制到本地”?是不是 true,不是的話弄成 true。在工程中開頭添加 using 語句:
using?System.Data.SQLite;
網上很多教程到這就ok了,但在我實際操作中,發現還要把?SQLite.Interop.dll?也拷貝到當前程序運行目錄下(不能引用,只能直接拷貝),不知道是不是新版本的要求。
(ps:在 sqlite 的安裝目錄下有很詳細的幫助文檔 SQLite.NET.chm)
二、數據類型
儲存的數據類型有以下5種:
| NULL | 一個NULL值 |
| INTERGER | 帶符號的整數,根據值的大小,自動存儲為1,2,3,4,5,8字節6種 |
| REAL | 浮點數,存儲為IEEE 8byte浮點數 |
| TEXT | 文本字符串,缺省的編碼為utf-8 |
| BLOG | blob數據,不定長 |
注意了,SQLite 的存儲寬度是根據輸入來自動調整的,這點和原來我用過的 foxpro 不一樣,比如就算你在 create 數據表中設定了一個字段 varchar(4) 4byte寬的字符串,但你輸入了“hello”5個寬度的字符串時,它并不會截取成“hell”,而是完整地存儲為“hello”。數字類型也是如此。
還有更有趣的是,它有個Type Affinity 功能,比如如下:
CREATE TABLE t1(a INT, b VARCHAR(10));
INSERT INTO t1(a,b) VALUES('123',456);
它會運用 Type Affinity 功能自動正確地把 "123" 轉換成數字,把 456轉化成“456”字符串。這個Type Affinity 請參考安裝目錄下的 幫助文件或?SQLite 親和(Affinity)類型。
三、創建數據庫
SQLite 是文件型的數據庫,創建很簡單,直接指定一個數據庫文件名,后綴名不一定非得是“.sqlite”,后綴隨便命名為".db"也成。運行 SQLiteConnection.open 就會創建個空的指定名字的數據庫文件。由于它是文件型的,我們也可以直接用 System.IO.File.Create() 來創建一個空的文件。
using?System.Data.SQLite;
//---創建數據庫
static?void?CreateDB()
{
????string?path = @"d:\test\123.sqlite";
????SQLiteConnection cn =?new?SQLiteConnection("data source=" + path);
????cn.Open();
????cn.Close();
}
?
四、刪除數據庫
sqlite 命令中好像沒有提供刪除整個數據庫的命令,但是由于它是個文件型的,我們直接用 System.IO.File.Delete(string path) 方法來刪除文件。
//---刪除數據庫
static?void?DeleteDB()
{
????string?path = @"d:\test\123.sqlite";
????if?(System.IO.File.Exists(path))
????{
????????System.IO.File.Delete(path);
????}
}
?
五、創建表
開始要用到 SQL 命令了。建立一個表的順序如下步驟(也可以用可視化工具 SQLiteExpert 來創建):
1、建立數據庫連接;
2、打開數據庫(如果沒有數據庫,Open 也會新創建一個數據庫);
3、聲明一個 SQLiteCommand 類,主要用來放置和運行 SQL 命令的;
4、把 SQLiteCommand 的 Connection 和 SQLiteConnection 聯系起來(切記,經常忘^_^!);
5、往 SQLiteCommand 的 CommandText 輸入 SQL 語句 CREATE TABLE 語句,具體請參考 安裝目錄下的 SQLite.NET.chm 或?SQLite 創建表;
6、調用 SQLiteCommand.ExcuteNonQuery() 方法運行。
//---添加表
static?void?CreateTable()
{
????string?path = @"d:\test\123.sqlite";
????SQLiteConnection cn =?new?SQLiteConnection("data source="+path);
????if?(cn.State!= System.Data.ConnectionState.Open)
????{
????????cn.Open();
????????SQLiteCommand cmd =?new?SQLiteCommand();
????????cmd.Connection = cn;
????????cmd.CommandText = "CREATE TABLE t1(id varchar(4),score?int)";
????????//cmd.CommandText = "CREATE TABLE IF NOT EXISTS t1(id varchar(4),score int)";
????????cmd.ExecuteNonQuery();
????}
????cn.Close();
}
注意上面那句被注釋掉的 CREATE TABEL IF NOT EXISTS ,一般情況下用這句比較好,如果原來就有同名的表,沒有這句就會出錯。SQL 語句其實也不用全部大寫,全部大寫是 SQL 語句約定俗成的(令我想起讀書的時候學的 COBOL),全部小寫也不會出錯。
六、刪除表
和建立表的步驟一樣,只是把 SQL 語句改了而已。
//---刪除表
static?void?DeleteTable()
{
????string?path = @"d:\test\123.sqlite";
????SQLiteConnection cn =?new?SQLiteConnection("data source=" + path);
????if?(cn.State != System.Data.ConnectionState.Open)
????{
????????cn.Open();
????????SQLiteCommand cmd =?new?SQLiteCommand();
????????cmd.Connection = cn;
????????cmd.CommandText =?"DROP TABLE IF EXISTS t1";
????????cmd.ExecuteNonQuery();
????}
????cn.Close();
}
?
七、查詢表結構
需要用到 SQLite 特殊的 PRAGMA 命令, 具體參見?PRAGMA Statements
PRAGMA table_info(tablename)?,tablename 用或不用單引號 ' ' 括起來都一樣。
SQliteDataReader 讀出來的數據順序代表:
| 0 | cid | 序號 |
| 1 | name | 名字 |
| 2 | type | 數據類型 |
| 3 | notnull | 能否null值,0不能,1 能 |
| 4 | dflt_value | 缺省值 |
| 5 | pk | 是否主鍵primary key,0否,1是 |
string?path = @"d:\test\123.sqlite";
SQLiteConnection cn =?new?SQLiteConnection("data source=" + path);
cn.Open();
SQLiteCommand cmd = cn.CreateCommand();
cmd.CommandText= "PRAGMA table_info('t1')";
//寫法一:用DataAdapter和DataTable類,記得要 using System.Data
SQLiteDataAdapter adapter =?new?SQLiteDataAdapter(cmd);
DataTable table =?new?DataTable();
adapter.Fill(table);
foreach(DataRow r?in?table.Rows)
{
????Console.WriteLine($"{r["cid"]},{r["name"]},{r["type"]},{r["notnull"]},{r["dflt_value"]},{r["pk"]} ");
}
Console.WriteLine();
//寫法二:用DataReader,這個效率高些
SQLiteDataReader reader = cmd.ExecuteReader();
while?(reader.Read())
{
????for(int?i = 0; i < reader.FieldCount; i++)
????{
????????Console.Write($"{reader[i]},");
????}
????Console.WriteLine();
}
reader.Close();
?
如果不止一個表,要遍歷所有表的結構如下,就要用到 SQLite 中的特殊表 sqlite_master,它的結構如下:
參考:
2.6. Storage Of The SQL Database Schema
CREATE TABLE sqlite_master(
type text,
name text,
tbl_name text,
rootpage integer,
sql text
);
當 type = table 時,name 和 tbl_name 是一樣的,其他比如 type =index 、view 之類時,tbl_name 才是表名。
//---遍歷查詢表結構
static?void?QueryAllTableInfo()
{
????string?path = @"d:\test\123.sqlite";
????SQLiteConnection cn =?new?SQLiteConnection("data source=" + path);
????if?(cn.State != System.Data.ConnectionState.Open)
????{
????????cn.Open();
????????SQLiteCommand cmd =?new?SQLiteCommand();
????????cmd.Connection = cn;
????????cmd.CommandText = "SELECT name FROM sqlite_master WHERE TYPE='table' ";
????????SQLiteDataReader sr = cmd.ExecuteReader();
????????List<string> tables =?new?List<string>();
????????while?(sr.Read())
????????{
????????????tables.Add(sr.GetString(0));
????????}
????????//datareader 必須要先關閉,否則 commandText 不能賦值
????????sr.Close();
????????foreach?(var?a?in?tables)
????????{
????????????cmd.CommandText = $"PRAGMA TABLE_INFO({a})";
????????????sr = cmd.ExecuteReader();
????????????while?(sr.Read())
????????????{
????????????????Console.WriteLine($"{sr[0]} {sr[1]} {sr[2]} {sr[3]}");
????????????}
????????????sr.Close();
????????}
????}
????cn.Close();
}
?
八、更改表名
用 SQL 語句 ALTER TABLE 把 t1 表名改成 t3:
cmd.CommandText =?"ALTER TABLE t1 RENAME TO t3";
cmd.ExecuteNonQuery();
注意,表名是不分大小寫的,也不用加單引號括起來。
九、增添列(字段)
還是用 SQL 命令 ALTER TABLE ,下例中為 t1 表添加一個名為 age,數據類型為 int 的新列:
cmd.CommandText =?"ALTER TABLE t1 ADD COLUMN age int";
cmd.ExecuteNonQuery();
十、讀取創建表的 SQL 語句
讀取創建表時的 SQL 語句,在 SqliteExpert 中的 DDL 可以查看到。讀取這個是為下面增添刪除列做準備。
cmd.CommandText =?"SELECT sql FROM sqlite_master WHERE TYPE='table'";
SQLiteDataReader sr = cmd.ExecuteReader();
while?(sr.Read())
{
????Console.WriteLine(sr[0].ToString());
}
sr.Close();
?
十一、更改列名
SQLite 中并沒有提供直接更改列名與刪除列的命令,有兩種方式,
第一種是:
1、把目標表改名;
2、創建一個帶有新列名的新表;
3、把舊表數據拷貝至新表(記得要 Connection.BeginTransaction())。
第二種是更改 sqlite_master 里面的 schema,很容易損壞數據庫。
依據是 SQLite 每次連接時,其實都是依據 schema 里面的每個表創建時的 CREATE TABLE 語句來動態建立 column 的信息的,只要 column 的數據類型和位置不變,更改 CREATE TABLE 語句就能更改 column 的信息。具體參考?How do I rename a column in a SQLite database table?。以下我們兩種方法都寫來看看。
方式一:
//---更改列名1
//總思路:把舊表更名,建個帶新列名的新表,拷貝數據
//params string[] 中:0 數據庫名,1 表名,2 舊列名 3 新列名
static?void?RenameColumn1(params?string[] str)
{
????SQLiteConnection cn =?new?SQLiteConnection("data source=" + str[0]);
????cn.Open();
????SQLiteCommand cmd =?new?SQLiteCommand();
????cmd.Connection = cn;
????
????//取得str[1]表名的表的建表SQL語句?
????cmd.CommandText = "SELECT name,sql FROM sqlite_master WHERE TYPE='table' ORDER BY name";
????SQLiteDataReader sr = cmd.ExecuteReader();
????string?_sql = "";?
????while?(sr.Read())
????{
????????if?(string.Compare(sr.GetString(0), str[1],?true) == 0)
????????{
????????????_sql = sr.GetString(1);
????????????break;
????????}
????}
????sr.Close();
????//更改舊表名為 帶 _old?
????string?_old = str[1] + "_old";
????cmd.CommandText = $"ALTER TABLE {str[1]} RENAME TO {_old}";
????cmd.ExecuteNonQuery();
????//建立新表,假設輸入的舊列名和表中的列名大小寫等完全一致,不寫能容錯的了
????_sql = _sql.Replace(str[2],str[3]);
????cmd.CommandText = _sql;
????cmd.ExecuteNonQuery();
????//拷貝數據
????using?(SQLiteTransaction tr = cn.BeginTransaction())
????{
????????cmd.CommandText = $"INSERT INTO {str[1]} SELECT * FROM {_old}";
????????cmd.ExecuteNonQuery();
????????cmd.CommandText = $"DROP TABLE {_old}";
????????cmd.ExecuteNonQuery();
????????tr.Commit();
????}
????cn.Close();
}
?
方式二:
//---更改列名2,改寫schema里建表時的sql語句
//原理:sqlite 每次打開的時候,都是依據建表時的sql語句來動態建立column的信息的
static?void?RenameColumn2(params?string[] str)
{
????SQLiteConnection cn =?new?SQLiteConnection("data source=" + str[0]);
????cn.Open();
????SQLiteCommand cmd =?new?SQLiteCommand();
????cmd.Connection = cn;
????//取得str[1]表名的表的建表SQL語句?
????cmd.CommandText = $"SELECT sql FROM sqlite_master WHERE TYPE='table' AND name='{str[1]}'";
????SQLiteDataReader sr = cmd.ExecuteReader();
????sr.Read();
????string?_sql = sr.GetString(0);
????sr.Close();
????//注意單引號 '
????_sql =$"UPDATE sqlite_master SET sql='{_sql.Replace(str[2],str[3])}' WHERE name= '{str[1]}' ";
????//設置 writable_schema 為 true,準備改寫schema?
????cmd.CommandText = "pragma writable_schema=1";
????cmd.ExecuteNonQuery();
????cmd.CommandText = _sql;
????cmd.ExecuteNonQuery();
????//設置 writable_schema 為 false。
????cmd.CommandText = "pragma writable_schema=0";
????cmd.ExecuteNonQuery();
????cn.Close();
}
?
十二、刪除列
SQLite 也沒有提供刪除列的命令。和上面一樣,也是兩種方式。
其一,把目標表改名,建立沒有要刪除列(字段)的新表,然后把舊表的數據拷貝至新表。
其二,直接修改 schema 中建表的 SQL 語句。
其中最主要的是要把建表的列的所有信息都保存下來,比如索引、缺省值之類的。下面示例使用第二種方式。
//---刪除列2,string[] ,0 數據庫路徑,1 表名,2 要刪除的列名
static?void?DeleteColumn2(params?string[] str)
{
????SQLiteConnection cn =?new?SQLiteConnection("data source=" + str[0]);
????cn.Open();
????SQLiteCommand cmd =?new?SQLiteCommand();
????cmd.Connection = cn;
????//取得str[1]表名的表的建表SQL語句?
????cmd.CommandText = $"SELECT sql FROM sqlite_master WHERE TYPE='table' AND name='{str[1]}'";
????SQLiteDataReader sr = cmd.ExecuteReader();
????sr.Read();
????string?_sql = sr.GetString(0);
????sr.Close();
????//取得列的定義
????//C#7.0的新特征,Tuple<>的語法糖,需要 NuGet install-package system.valuetuple
????List<(string?name,?string?define)> list = GetColumnDefine(_sql);
????//取得要刪除列的序號
????int?_index = list.IndexOf(list.Where(x => x.name == str[2]).First());
????//建立新的sql語句
????StringBuilder sb =?new?StringBuilder();
????sb.Append($"CREATE TABLE {str[1]}(");
????for?(int?i = 0; i < list.Count; i++)
????{
????????if?(i != _index)
????????{
????????????sb.Append($"{list[i].define},");
????????}
????}
????sb.Remove(sb.Length - 1, 1);
????sb.Append(")");
????//改寫schema
????_sql = $"UPDATE sqlite_master SET sql='{sb.ToString()}' WHERE name='{str[1]}'";
????//設置 writable_schema 為 true,準備改寫schema?
????cmd.CommandText = "pragma writable_schema=1";
????cmd.ExecuteNonQuery();
????cmd.CommandText = _sql;
????cmd.ExecuteNonQuery();
????//設置 writable_schema 為 false。
????cmd.CommandText = "pragma writable_schema=0";
????cmd.ExecuteNonQuery();
????cn.Close();
}
//---取得列的定義
static?List<(string,?string)> GetColumnDefine(string?SqlStr)
{
????int?n = 0;
????int?_start = 0;
????string?_columnStr = "";
????for?(int?i = 0; i < SqlStr.Length; i++)
????{
????????if?(SqlStr[i] == '(')
????????{
????????????if?(n++ == 0) { _start = i; }
????????}
????????else
????????{
????????????if?(SqlStr[i] == ')')
????????????{
????????????????if?(--n == 0)
????????????????{
????????????????????_columnStr = SqlStr.Substring(_start + 1, i - _start - 1);
????????????????????break;
????????????????}
????????????}
????????}
????}
????string[] ss = _columnStr.Split(new?char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
????//C#7.0的新特征,Tuple<>的語法糖,需要 NuGet install-package system.valuetuple
????List<(string?name,?string?define)> reslut =?new?List<(string?name,?string?define)>();
????foreach?(var?a?in?ss)
????{
????????string?s = a.Trim();
????????n = 0;
????????for?(int?i = 0; i < s.Length; i++)
????????{
????????????if?(s[i] == ' ')
????????????{
????????????????reslut.Add((s.Substring(0, i), s));
????????????????break;
????????????}
????????}
????}
????return?reslut;
}
?
十三、插入數據
插入數據主要是用 SQL 語句 INSERT INTO
示例1(簡單插入):
cmd.CommandText = "INSERT INTO t1 VALUES('99999',11)";
cmd.ExecuteNonQuery();
?
示例2(變量插入,要引用 System.Data):
using?System.Data;
string?s = "123456";
int?n = 10;
cmd.CommandText = "INSERT INTO t1(id,age) VALUES(@id,@age)";
cmd.Parameters.Add("id", DbType.String).Value = s;
cmd.Parameters.Add("age", DbType.Int32).Value = n;
cmd.ExecuteNonQuery();
?
十四、替換數據
SQL 命令 INSERT INTO。
下面示例中, t1 表中 id 為主鍵,相同主鍵值的就 UPDATE,否則就 INSERT
string?s = "123456";
int?n = 30;
cmd.CommandText = "REPLACE INTO t1(id,age) VALUES(@id,@age)";
cmd.Parameters.Add("id", DbType.String).Value = s;
cmd.Parameters.Add("age", DbType.Int32).Value = n;
cmd.ExecuteNonQuery();
?
十五、更新數據
SQL 命令 UPDATE tablename SET column1=value,column2=value... WHERE 條件
string?s = "333444";
int?n = 30;
cmd.CommandText = "UPDATE t1 SET id=@id,age=@age WHERE id='0123456789'";
cmd.Parameters.Add("id", DbType.String).Value = s;
cmd.Parameters.Add("age", DbType.Int32).Value = n;
cmd.ExecuteNonQuery();
?
十六、刪除數據
SQL 命令:DELETE FROM tablename WHERE 條件
cmd.CommandText = "DELETE FROM t1 WHERE id='99999'";
cmd.ExecuteNonQuery();
?
十七、查詢數據
SQL 命令:SELETE 語句,具體的請參考?SQL 教程。
//查詢第1條記錄,這個并不保險,rowid 并不是連續的,只是和當時插入有關
cmd.CommandText = "SELECT * FROM t1 WHERE rowid=1";
SQLiteDataReader sr = cmd.ExecuteReader();
while?(sr.Read())
{
????Console.WriteLine($"{sr.GetString(0)} {sr.GetInt32(1).ToString()}");
}
sr.Close();
//運行以下的就能知道 rowid 并不能代表 行數
cmd.CommandText = "SELECT rowid FROM t1 ";
sr = cmd.ExecuteReader();
while?(sr.Read())
{
????Console.WriteLine($"{sr.GetString(0)} {sr.GetInt32(1).ToString()}");
}
sr.Close();
?
十八、獲取查詢數據的行數(多少條記錄)
從上面示例中我們得知,rowid 并不是正確的行數(記錄數),而是 INSERT 的時候的B-Tree 的相關數。
如要知道表中的行數(記錄數),要如下:
cmd.CommandText = "SELECT count(*) FROM t1";
sr = cmd.ExecuteReader();
sr.Read();
Console.WriteLine(sr.GetInt32(0).ToString());
sr.Close();
?
十九、事務
事務就是對數據庫一組按邏輯順序操作的執行單元。用事務的好處就是成熟的數據庫都對 密集型的磁盤 IO 操作之類進行優化,而且還能進行撤回回滾操作。其實在上面改變列名的示例中就用過。
//---事務
static?void?TransActionOperate(SQLiteConnection cn,SQLiteCommand cmd)
{
????using?(SQLiteTransaction tr = cn.BeginTransaction())?
????{
????????string?s = "";
????????int?n = 0;
????????cmd.CommandText = "INSERT INTO t2(id,score) VALUES(@id,@score)";
????????cmd.Parameters.Add("id", DbType.String);
????????cmd.Parameters.Add("score", DbType.Int32);
????????for?(int?i = 0; i < 10; i++)
????????{
????????????s = i.ToString();
????????????n = i;
????????????cmd.Parameters[0].Value = s;
????????????cmd.Parameters[1].Value = n;
????????????cmd.ExecuteNonQuery();
????????}
????????tr.Commit();
????}
}
?
二十、整理數據庫
SQLite 的自帶命令 VACUUM。用來重新整理整個數據庫達到緊湊之用,比如把刪除的徹底刪掉等等。
cmd.CommandText = "VACUUM";
cmd.ExecuteNonQuery();
?
到這里 SQLite 數據庫基本上能操作了,至于那些用 linq 操作等的需要安裝 ORM 的,我想了一下,下次再學習吧。對于我的小項目來說,帶著兩個加起來不到 1.5M的 dll ,還是很簡練的。
SQLite 也是數據庫,主要的還是各種 SQL 語句的調用,著眼于 SQL 語句的學習是下段時間我折騰的目標。
看到滿大街的 SQLiteHelper ,我想了下,就我這水平就不班門弄斧了,即使我也會偷偷寫個,方便調用。
總結
以上是生活随笔為你收集整理的C# SQLite 数据库操作语句与文件视图管理器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 字符串拆分成单个字符放到 li
- 下一篇: mysql 索引:类型 、创建