日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

C# SQLite 数据库操作实例2

發(fā)布時(shí)間:2023/12/18 C# 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# SQLite 数据库操作实例2 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

運(yùn)行環(huán)境:Window7 64bit,.NetFramework4.61,C# 7.0


參考:

  • SQLite 官網(wǎng)
  • SQL As Understood By SQLite
  • System.Data.SQLite
  • 菜鳥教程
  • SQL 教程

章節(jié):

  • 1、下載安裝
  • 2、數(shù)據(jù)類型
  • 3、創(chuàng)建數(shù)據(jù)庫(kù)
  • 4、刪除數(shù)據(jù)庫(kù)
  • 5、創(chuàng)建表
  • 6、刪除表
  • 7、查詢表結(jié)構(gòu)
  • 8、更改表名
  • 9、增加列(字段)
  • 10、讀取創(chuàng)建表的 SQL 語(yǔ)句
  • 11、更改列名
  • 12、刪除列
  • 13、插入數(shù)據(jù)
  • 14、替換數(shù)據(jù)
  • 15、更新數(shù)據(jù)
  • 16、刪除數(shù)據(jù)
  • 17、查詢數(shù)據(jù)
  • 18、獲取查詢數(shù)據(jù)的行數(shù)(多少條記錄)
  • 19、事務(wù) Transaction
  • 20、整理數(shù)據(jù)庫(kù)

正文:

一、下載安裝

這段時(shí)間在學(xué)習(xí) C# 編程中,想寫一個(gè)簡(jiǎn)單的進(jìn)銷存程序,就想到了用數(shù)據(jù)庫(kù),需要一個(gè)簡(jiǎn)單便攜的桌面數(shù)據(jù)庫(kù),想自己寫個(gè),功力太淺,可以做為以后練手學(xué)習(xí)的項(xiàng)目。原來會(huì)用的 Foxpro 已經(jīng)被微軟不知丟在哪個(gè)旮旯了,在網(wǎng)上找了一下,發(fā)現(xiàn)只有 Access 和 Sqlite 可選,看了很多對(duì)比,決定還是學(xué)習(xí)使用 Sqlite。

在?System.Data.SQLite 官網(wǎng)的 download 中的 Setups for 64-bit Windows (.NET Framework 4.6)?sqlite-netFx46-setup-x64-2015-1.0.104.0.exe (17.99 MiB)?下載然后運(yùn)行安裝。
更簡(jiǎn)單的做法是在 Visual Studio 2017 的 NuGet 中,輸入:install-package system.data.sqlite.x64。

sqlite數(shù)據(jù)庫(kù)的可視化工具中,?SqliteExpert?不錯(cuò),下載?SQLite Expert Personal 4.x?。

工具備齊了,由于知道上面這個(gè)System data Sqlite 是用 C# 封裝好的,下來我們打開Visual Studio 2017,新開個(gè)工程,在菜單“項(xiàng)目”→“添加引用”→“瀏覽”?中,去 Sqlite 的安裝目錄下選擇 System.Data.SQLite.dll,才305k的鏈接庫(kù)。引用了后,在VS右上角的“解決方案資源管理器”中看看引用下的 System.Data.SQlite 的引用屬性中的“復(fù)制到本地”?是不是 true,不是的話弄成 true。在工程中開頭添加 using 語(yǔ)句:

using?System.Data.SQLite;

網(wǎng)上很多教程到這就ok了,但在我實(shí)際操作中,發(fā)現(xiàn)還要把?SQLite.Interop.dll?也拷貝到當(dāng)前程序運(yùn)行目錄下(不能引用,只能直接拷貝),不知道是不是新版本的要求。

(ps:在 sqlite 的安裝目錄下有很詳細(xì)的幫助文檔 SQLite.NET.chm)

二、數(shù)據(jù)類型

儲(chǔ)存的數(shù)據(jù)類型有以下5種:

存儲(chǔ)類描述
NULL一個(gè)NULL值
INTERGER帶符號(hào)的整數(shù),根據(jù)值的大小,自動(dòng)存儲(chǔ)為1,2,3,4,5,8字節(jié)6種
REAL浮點(diǎn)數(shù),存儲(chǔ)為IEEE 8byte浮點(diǎn)數(shù)
TEXT文本字符串,缺省的編碼為utf-8
BLOGblob數(shù)據(jù),不定長(zhǎng)

注意了,SQLite 的存儲(chǔ)寬度是根據(jù)輸入來自動(dòng)調(diào)整的,這點(diǎn)和原來我用過的 foxpro 不一樣,比如就算你在 create 數(shù)據(jù)表中設(shè)定了一個(gè)字段 varchar(4) 4byte寬的字符串,但你輸入了“hello”5個(gè)寬度的字符串時(shí),它并不會(huì)截取成“hell”,而是完整地存儲(chǔ)為“hello”。數(shù)字類型也是如此。

還有更有趣的是,它有個(gè)Type Affinity 功能,比如如下:

CREATE TABLE t1(a INT, b VARCHAR(10));
INSERT INTO t1(a,b) VALUES('123',456);

它會(huì)運(yùn)用 Type Affinity 功能自動(dòng)正確地把 "123" 轉(zhuǎn)換成數(shù)字,把 456轉(zhuǎn)化成“456”字符串。這個(gè)Type Affinity 請(qǐng)參考安裝目錄下的 幫助文件或?SQLite 親和(Affinity)類型。

三、創(chuàng)建數(shù)據(jù)庫(kù)

SQLite 是文件型的數(shù)據(jù)庫(kù),創(chuàng)建很簡(jiǎn)單,直接指定一個(gè)數(shù)據(jù)庫(kù)文件名,后綴名不一定非得是“.sqlite”,后綴隨便命名為".db"也成。運(yùn)行 SQLiteConnection.open 就會(huì)創(chuàng)建個(gè)空的指定名字的數(shù)據(jù)庫(kù)文件。由于它是文件型的,我們也可以直接用 System.IO.File.Create() 來創(chuàng)建一個(gè)空的文件。

using?System.Data.SQLite;
//---創(chuàng)建數(shù)據(jù)庫(kù)
static?void?CreateDB()
{
????string?path = @"d:\test\123.sqlite";
????SQLiteConnection cn =?new?SQLiteConnection("data source=" + path);
????cn.Open();
????cn.Close();
}
?

四、刪除數(shù)據(jù)庫(kù)

sqlite 命令中好像沒有提供刪除整個(gè)數(shù)據(jù)庫(kù)的命令,但是由于它是個(gè)文件型的,我們直接用 System.IO.File.Delete(string path) 方法來刪除文件。

//---刪除數(shù)據(jù)庫(kù)
static?void?DeleteDB()
{
????string?path = @"d:\test\123.sqlite";
????if?(System.IO.File.Exists(path))
????{
????????System.IO.File.Delete(path);
????}
}
?

五、創(chuàng)建表

開始要用到 SQL 命令了。建立一個(gè)表的順序如下步驟(也可以用可視化工具 SQLiteExpert 來創(chuàng)建):
1、建立數(shù)據(jù)庫(kù)連接;
2、打開數(shù)據(jù)庫(kù)(如果沒有數(shù)據(jù)庫(kù),Open 也會(huì)新創(chuàng)建一個(gè)數(shù)據(jù)庫(kù));
3、聲明一個(gè) SQLiteCommand 類,主要用來放置和運(yùn)行 SQL 命令的;
4、把 SQLiteCommand 的 Connection 和 SQLiteConnection 聯(lián)系起來(切記,經(jīng)常忘^_^!);
5、往 SQLiteCommand 的 CommandText 輸入 SQL 語(yǔ)句 CREATE TABLE 語(yǔ)句,具體請(qǐng)參考 安裝目錄下的 SQLite.NET.chm 或?SQLite 創(chuàng)建表;
6、調(diào)用 SQLiteCommand.ExcuteNonQuery() 方法運(yùn)行。

//---添加表
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 ,一般情況下用這句比較好,如果原來就有同名的表,沒有這句就會(huì)出錯(cuò)。SQL 語(yǔ)句其實(shí)也不用全部大寫,全部大寫是 SQL 語(yǔ)句約定俗成的(令我想起讀書的時(shí)候?qū)W的 COBOL),全部小寫也不會(huì)出錯(cuò)。

六、刪除表

和建立表的步驟一樣,只是把 SQL 語(yǔ)句改了而已。

//---刪除表
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();
}
?

七、查詢表結(jié)構(gòu)

需要用到 SQLite 特殊的 PRAGMA 命令, 具體參見?PRAGMA Statements
PRAGMA table_info(tablename)?,tablename 用或不用單引號(hào) ' ' 括起來都一樣。
SQliteDataReader 讀出來的數(shù)據(jù)順序代表:

下標(biāo)名稱描述
0cid序號(hào)
1name名字
2type數(shù)據(jù)類型
3notnull能否null值,0不能,1 能
4dflt_value缺省值
5pk是否主鍵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,這個(gè)效率高些
SQLiteDataReader reader = cmd.ExecuteReader();
while?(reader.Read())
{
????for(int?i = 0; i < reader.FieldCount; i++)
????{
????????Console.Write($"{reader[i]},");
????}
????Console.WriteLine();
}
reader.Close();
?

如果不止一個(gè)表,要遍歷所有表的結(jié)構(gòu)如下,就要用到 SQLite 中的特殊表 sqlite_master,它的結(jié)構(gòu)如下:
參考:
2.6. Storage Of The SQL Database Schema
CREATE TABLE sqlite_master(
type text,
name text,
tbl_name text,
rootpage integer,
sql text
);
當(dāng) type = table 時(shí),name 和 tbl_name 是一樣的,其他比如 type =index 、view 之類時(shí),tbl_name 才是表名。

//---遍歷查詢表結(jié)構(gòu)
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 必須要先關(guān)閉,否則 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 語(yǔ)句 ALTER TABLE 把 t1 表名改成 t3:

cmd.CommandText =?"ALTER TABLE t1 RENAME TO t3";
cmd.ExecuteNonQuery();

注意,表名是不分大小寫的,也不用加單引號(hào)括起來。

九、增添列(字段)

還是用 SQL 命令 ALTER TABLE ,下例中為 t1 表添加一個(gè)名為 age,數(shù)據(jù)類型為 int 的新列:

cmd.CommandText =?"ALTER TABLE t1 ADD COLUMN age int";
cmd.ExecuteNonQuery();

十、讀取創(chuàng)建表的 SQL 語(yǔ)句

讀取創(chuàng)建表時(shí)的 SQL 語(yǔ)句,在 SqliteExpert 中的 DDL 可以查看到。讀取這個(gè)是為下面增添刪除列做準(zhǔn)備。

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、把目標(biāo)表改名;
2、創(chuàng)建一個(gè)帶有新列名的新表;
3、把舊表數(shù)據(jù)拷貝至新表(記得要 Connection.BeginTransaction())。

第二種是更改 sqlite_master 里面的 schema,很容易損壞數(shù)據(jù)庫(kù)。
依據(jù)是 SQLite 每次連接時(shí),其實(shí)都是依據(jù) schema 里面的每個(gè)表創(chuàng)建時(shí)的 CREATE TABLE 語(yǔ)句來動(dòng)態(tài)建立 column 的信息的,只要 column 的數(shù)據(jù)類型和位置不變,更改 CREATE TABLE 語(yǔ)句就能更改 column 的信息。具體參考?How do I rename a column in a SQLite database table?。以下我們兩種方法都寫來看看。

方式一:

//---更改列名1
//總思路:把舊表更名,建個(gè)帶新列名的新表,拷貝數(shù)據(jù)
//params string[] 中:0 數(shù)據(jù)庫(kù)名,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語(yǔ)句?
????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();

????//建立新表,假設(shè)輸入的舊列名和表中的列名大小寫等完全一致,不寫能容錯(cuò)的了
????_sql = _sql.Replace(str[2],str[3]);
????cmd.CommandText = _sql;
????cmd.ExecuteNonQuery();

????//拷貝數(shù)據(jù)
????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里建表時(shí)的sql語(yǔ)句
//原理:sqlite 每次打開的時(shí)候,都是依據(jù)建表時(shí)的sql語(yǔ)句來動(dòng)態(tài)建立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語(yǔ)句?
????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();
????//注意單引號(hào) '
????_sql =$"UPDATE sqlite_master SET sql='{_sql.Replace(str[2],str[3])}' WHERE name= '{str[1]}' ";

????//設(shè)置 writable_schema 為 true,準(zhǔn)備改寫schema?
????cmd.CommandText = "pragma writable_schema=1";
????cmd.ExecuteNonQuery();
????cmd.CommandText = _sql;
????cmd.ExecuteNonQuery();
????//設(shè)置 writable_schema 為 false。
????cmd.CommandText = "pragma writable_schema=0";
????cmd.ExecuteNonQuery();

????cn.Close();
}
?

十二、刪除列

SQLite 也沒有提供刪除列的命令。和上面一樣,也是兩種方式。
其一,把目標(biāo)表改名,建立沒有要?jiǎng)h除列(字段)的新表,然后把舊表的數(shù)據(jù)拷貝至新表。
其二,直接修改 schema 中建表的 SQL 語(yǔ)句。
其中最主要的是要把建表的列的所有信息都保存下來,比如索引、缺省值之類的。下面示例使用第二種方式。

//---刪除列2,string[] ,0 數(shù)據(jù)庫(kù)路徑,1 表名,2 要?jiǎng)h除的列名
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語(yǔ)句?
????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<>的語(yǔ)法糖,需要 NuGet install-package system.valuetuple
????List<(string?name,?string?define)> list = GetColumnDefine(_sql);
????//取得要?jiǎng)h除列的序號(hào)
????int?_index = list.IndexOf(list.Where(x => x.name == str[2]).First());
????//建立新的sql語(yǔ)句
????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]}'";
????//設(shè)置 writable_schema 為 true,準(zhǔn)備改寫schema?
????cmd.CommandText = "pragma writable_schema=1";
????cmd.ExecuteNonQuery();
????cmd.CommandText = _sql;
????cmd.ExecuteNonQuery();
????//設(shè)置 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<>的語(yǔ)法糖,需要 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;
}
?

十三、插入數(shù)據(jù)

插入數(shù)據(jù)主要是用 SQL 語(yǔ)句 INSERT INTO

示例1(簡(jiǎn)單插入):

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();
?

十四、替換數(shù)據(jù)

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();
?

十五、更新數(shù)據(jù)

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();
?

十六、刪除數(shù)據(jù)

SQL 命令:DELETE FROM tablename WHERE 條件

cmd.CommandText = "DELETE FROM t1 WHERE id='99999'";
cmd.ExecuteNonQuery();
?

十七、查詢數(shù)據(jù)

SQL 命令:SELETE 語(yǔ)句,具體的請(qǐng)參考?SQL 教程。

//查詢第1條記錄,這個(gè)并不保險(xiǎn),rowid 并不是連續(xù)的,只是和當(dāng)時(shí)插入有關(guān)
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();
//運(yùn)行以下的就能知道 rowid 并不能代表 行數(shù)
cmd.CommandText = "SELECT rowid FROM t1 ";
sr = cmd.ExecuteReader();
while?(sr.Read())
{
????Console.WriteLine($"{sr.GetString(0)} {sr.GetInt32(1).ToString()}");
}
sr.Close();
?

十八、獲取查詢數(shù)據(jù)的行數(shù)(多少條記錄)

從上面示例中我們得知,rowid 并不是正確的行數(shù)(記錄數(shù)),而是 INSERT 的時(shí)候的B-Tree 的相關(guān)數(shù)。
如要知道表中的行數(shù)(記錄數(shù)),要如下:

cmd.CommandText = "SELECT count(*) FROM t1";
sr = cmd.ExecuteReader();
sr.Read();
Console.WriteLine(sr.GetInt32(0).ToString());
sr.Close();
?

十九、事務(wù)

事務(wù)就是對(duì)數(shù)據(jù)庫(kù)一組按邏輯順序操作的執(zhí)行單元。用事務(wù)的好處就是成熟的數(shù)據(jù)庫(kù)都對(duì) 密集型的磁盤 IO 操作之類進(jìn)行優(yōu)化,而且還能進(jìn)行撤回回滾操作。其實(shí)在上面改變列名的示例中就用過。

//---事務(wù)
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();
????}
}

?

二十、整理數(shù)據(jù)庫(kù)

SQLite 的自帶命令 VACUUM。用來重新整理整個(gè)數(shù)據(jù)庫(kù)達(dá)到緊湊之用,比如把刪除的徹底刪掉等等。

cmd.CommandText = "VACUUM";
cmd.ExecuteNonQuery();
?


到這里 SQLite 數(shù)據(jù)庫(kù)基本上能操作了,至于那些用 linq 操作等的需要安裝 ORM 的,我想了一下,下次再學(xué)習(xí)吧。對(duì)于我的小項(xiàng)目來說,帶著兩個(gè)加起來不到 1.5M的 dll ,還是很簡(jiǎn)練的。
SQLite 也是數(shù)據(jù)庫(kù),主要的還是各種 SQL 語(yǔ)句的調(diào)用,著眼于 SQL 語(yǔ)句的學(xué)習(xí)。

總結(jié)

以上是生活随笔為你收集整理的C# SQLite 数据库操作实例2的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美精品在欧美一区二区 | 久热国产精品 | 日本在线小视频 | 巨乳女教师的诱惑 | 91精品专区 | 欧美色图视频在线 | 亚洲自拍另类 | 久久五月婷 | 密色av | 亚洲综合热 | 狠狠操网址 | 你懂的在线免费观看 | 无码精品在线观看 | 波多野结衣在线电影 | 成人手机在线观看 | 日日躁夜夜躁aaaabbbb | 成人亚洲精品久久久久软件 | 成年人黄色网址 | 免费国产成人 | 天天爱av | 91视频直接看| 成人区精品一区二区婷婷 | 伊人久久伊人 | 国产成人亚洲欧洲在线 | 国产亚洲AV无码成人网站在线 | 美女福利在线 | 北条麻妃99精品青青久久 | 国产手机在线观看 | 亚av在线 | 欧美大尺度床戏做爰 | 国产成人综合欧美精品久久 | 超碰人人干人人 | 天堂av资源在线观看 | 日韩在线视频播放 | 神马久久久久久久 | 一区二区三区成人 | 欧美色图另类 | 好吊视频一区二区三区 | 国产淫视频 | 国产福利免费在线观看 | 激情五月开心婷婷 | 制服丝袜中文字幕在线 | 欧美激情综合网 | 超碰在线国产 | 欧美伊人 | 亚洲av成人精品一区二区三区在线播放 | 天天毛片 | 人妻少妇精品无码专区久久 | 国产99久久久国产精品成人免费 | 爱爱小视频免费看 | 天天爱天天做天天爽 | 国产成人综合视频 | 国产一区资源 | 伊人精品在线 | 91精品国产高清一区二区三区蜜臀 | 色国产在线 | 五月天婷婷伊人 | 国产成人a v | 二十四小时在线更新观看 | 国产女人18水真多毛片18精品 | 成人高清在线观看 | 国产美女极度色诱视频www | 国产蜜臀在线 | 亚洲国产精华液网站w | 成人黄色免费在线观看 | 国产性―交一乱―色―情人 | 最近高清中文在线字幕在线观看 | 干美女少妇 | 亚洲久久一区 | 久久波多野结衣 | 欧美大片在线免费观看 | 成年人国产精品 | 精品一区二区三区久久 | 88xx成人永久免费观看 | 欧美高清hd18日本 | 黄色av网站在线免费观看 | 亚洲色图25p | 日本a级大片 | 久久久精品视频免费 | 欧美乱色 | 欧美成人另类 | 蜜桃久久一区二区三区 | 日本不卡123 | 视频一区二区在线播放 | 日本福利一区二区 | 干干日日 | 丰满肉肉bbwwbbww| 污视频网址在线观看 | jizz一区 | 国产精品国产三级国产aⅴ下载 | 少妇高潮露脸国语对白 | 国产黄色大片在线观看 | 国产深夜视频 | 欧美福利社 | 欧美在线性 | 国产大片b站| 九九香蕉视频 | 在线免费观看你懂的 | 丁香六月激情综合 |