VB.Net中创建新SQLite库并迁移旧数据的方法求助
VB.Net中SQLite表结构修正与数据迁移实现
核心需求
将现有SQLite数据库中TxData表的txYear和txSearchMonth字段从TEXT改为INTEGER,同时保留原有数据,解决搜索功能异常问题。以下是两种无需依赖命令行的VB.Net实现方案:
方案1:在现有数据库内直接迁移(推荐,无需新文件)
该方案通过创建临时表、迁移数据、替换原表的方式完成修改,无需删除旧数据库,风险更低。
步骤与代码
- 创建新结构的临时表
- 迁移数据并转换字段类型
- 替换原表(保留旧表作为备份)
Imports System.Data.SQLite Public Sub MigrateDataInExistingDatabase(oldDbFilePath As String) ' 连接旧数据库 Using conn As New SQLiteConnection($"Data Source={oldDbFilePath};Version=3;") conn.Open() ' 1. 创建符合要求的临时表 Dim createTempTableSql As String = "CREATE TABLE IF NOT EXISTS TxData_Temp( TID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, txSortDate TEXT, txYear INTEGER, txType TEXT, txAmount TEXT, txCKNum TEXT, txDesc TEXT, txBalance TEXT, txSearchMonth INTEGER)" Using cmd As New SQLiteCommand(createTempTableSql, conn) cmd.ExecuteNonQuery() End Using ' 2. 迁移数据,自动将TEXT类型的年份/月份转为INTEGER ' 若存在非数字内容,需提前处理或添加异常捕获 Dim migrateDataSql As String = "INSERT INTO TxData_Temp (txSortDate, txYear, txType, txAmount, txCKNum, txDesc, txBalance, txSearchMonth) SELECT txSortDate, CAST(txYear AS INTEGER), txType, txAmount, txCKNum, txDesc, txBalance, CAST(txSearchMonth AS INTEGER) FROM TxData" Using cmd As New SQLiteCommand(migrateDataSql, conn) cmd.ExecuteNonQuery() End Using ' 3. 重命名原表为备份,临时表改为原表名 Using cmd As New SQLiteCommand("ALTER TABLE TxData RENAME TO TxData_Backup", conn) cmd.ExecuteNonQuery() End Using Using cmd As New SQLiteCommand("ALTER TABLE TxData_Temp RENAME TO TxData", conn) cmd.ExecuteNonQuery() End Using ' 确认数据无误后,可删除备份表(可选) ' Using cmd As New SQLiteCommand("DROP TABLE TxData_Backup", conn) ' cmd.ExecuteNonQuery() ' End Using conn.Close() End Using End Sub
方案2:创建新数据库并迁移数据
适合需要保留原始数据库文件的场景,直接生成新的数据库文件。
步骤与代码
- 创建新数据库并建立正确表结构
- 从旧数据库读取数据,转换字段类型后插入新表
Imports System.Data.SQLite Public Sub MigrateToNewDatabase(oldDbFilePath As String, newDbFilePath As String) ' 连接旧数据库 Using oldConn As New SQLiteConnection($"Data Source={oldDbFilePath};Version=3;") oldConn.Open() ' 连接并初始化新数据库 Using newConn As New SQLiteConnection($"Data Source={newDbFilePath};Version=3;") newConn.Open() ' 1. 在新数据库创建正确结构的表 Dim createNewTableSql As String = "CREATE TABLE IF NOT EXISTS TxData( TID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, txSortDate TEXT, txYear INTEGER, txType TEXT, txAmount TEXT, txCKNum TEXT, txDesc TEXT, txBalance TEXT, txSearchMonth INTEGER)" Using cmd As New SQLiteCommand(createNewTableSql, newConn) cmd.ExecuteNonQuery() End Using ' 2. 从旧数据库读取数据并插入新表 Dim selectOldDataSql As String = "SELECT txSortDate, txYear, txType, txAmount, txCKNum, txDesc, txBalance, txSearchMonth FROM TxData" Using oldCmd As New SQLiteCommand(selectOldDataSql, oldConn) Using reader As SQLiteDataReader = oldCmd.ExecuteReader() ' 准备插入命令 Dim insertNewDataSql As String = "INSERT INTO TxData (txSortDate, txYear, txType, txAmount, txCKNum, txDesc, txBalance, txSearchMonth) VALUES (@txSortDate, @txYear, @txType, @txAmount, @txCKNum, @txDesc, @txBalance, @txSearchMonth)" Using newCmd As New SQLiteCommand(insertNewDataSql, newConn) ' 定义参数 newCmd.Parameters.Add("@txSortDate", DbType.String) newCmd.Parameters.Add("@txYear", DbType.Int32) newCmd.Parameters.Add("@txType", DbType.String) newCmd.Parameters.Add("@txAmount", DbType.String) newCmd.Parameters.Add("@txCKNum", DbType.String) newCmd.Parameters.Add("@txDesc", DbType.String) newCmd.Parameters.Add("@txBalance", DbType.String) newCmd.Parameters.Add("@txSearchMonth", DbType.Int32) ' 逐行处理数据 While reader.Read() newCmd.Parameters("@txSortDate").Value = reader("txSortDate") ' 处理可能的空值或非数字内容 newCmd.Parameters("@txYear").Value = If(reader.IsDBNull(reader.GetOrdinal("txYear")), DBNull.Value, Convert.ToInt32(reader("txYear"))) newCmd.Parameters("@txType").Value = reader("txType") newCmd.Parameters("@txAmount").Value = reader("txAmount") newCmd.Parameters("@txCKNum").Value = reader("txCKNum") newCmd.Parameters("@txDesc").Value = reader("txDesc") newCmd.Parameters("@txBalance").Value = reader("txBalance") newCmd.Parameters("@txSearchMonth").Value = If(reader.IsDBNull(reader.GetOrdinal("txSearchMonth")), DBNull.Value, Convert.ToInt32(reader("txSearchMonth"))) newCmd.ExecuteNonQuery() End While End Using End Using End Using newConn.Close() End Using oldConn.Close() End Using End Sub
关键注意事项
- 备份优先:操作前务必复制旧数据库文件作为备份,防止数据丢失
- 依赖准备:确保项目已引用
System.Data.SQLite库(可通过NuGet安装) - 异常处理:若
txYear或txSearchMonth存在非数字内容,需添加Try-Catch块捕获转换错误,提前清理数据 - 应用适配:迁移完成后,若使用方案2,需修改原应用中数据库连接的文件路径为新数据库路径
内容的提问来源于stack exchange,提问作者Vector
相关产品推荐
相关产品推荐

