使用子查询进行数据迁移处理
INSERT INTO t_message(messageID, messageType, messageJsonContent, retriveTimeString, postTimeString, readState) SELECT messageID, messageType, messageJsonContent, retriveTimeString, postTimeString, readState FROM t_message_bak
把t_message_bak表中的messageID, messageType, messageJsonContent, retriveTimeString, postTimeString, readState这些字段的值复制到t_message表中
代码实现
接下来就到了代码的实现步骤了
// 创建新的临时表,把数据导入临时表,然后用临时表替换原表 - (void)baseDBVersionControl { NSString * version_old = ValueOrEmpty(MMUserDefault.dbVersion); NSString * version_new = [NSString stringWithFormat:@"%@", DB_Version]; NSLog(@"dbVersionControl before: %@ after: %@",version_old,version_new); // 数据库版本升级 if (version_old != nil && ![version_new isEqualToString:version_old]) { // 获取数据库中旧的表 NSArray* existsTables = [self sqliteExistsTables]; NSMutableArray* tmpExistsTables = [NSMutableArray array]; // 修改表名,添加后缀“_bak”,把旧的表当做备份表 for (NSString* tablename in existsTables) { [tmpExistsTables addObject:[NSString stringWithFormat:@"%@_bak", tablename]]; [self.databaseQueue inDatabase:^(FMDatabase *db) { NSString* sql = [NSString stringWithFormat:@"ALTER TABLE %@ RENAME TO %@_bak", tablename, tablename]; [db executeUpdate:sql]; }]; } existsTables = tmpExistsTables; // 创建新的表 [self initTables]; // 获取新创建的表 NSArray* newAddedTables = [self sqliteNewAddedTables]; // 遍历旧的表和新表,对比取出需要迁移的表的字段 NSDictionary* migrationInfos = [self generateMigrationInfosWithOldTables:existsTables newTables:newAddedTables]; // 数据迁移处理 [migrationInfos enumerateKeysAndObjectsUsingBlock:^(NSString* newTableName, NSArray* publicColumns, BOOL * _Nonnull stop) { NSMutableString* colunmsString = [NSMutableString new]; for (int i = 0; i<publicColumns.count; i++) { [colunmsString appendString:publicColumns[i]]; if (i != publicColumns.count-1) { [colunmsString appendString:@", "]; } } NSMutableString* sql = [NSMutableString new]; [sql appendString:@"INSERT INTO "]; [sql appendString:newTableName]; [sql appendString:@"("]; [sql appendString:colunmsString]; [sql appendString:@")"]; [sql appendString:@" SELECT "]; [sql appendString:colunmsString]; [sql appendString:@" FROM "]; [sql appendFormat:@"%@_bak", newTableName]; [self.databaseQueue inDatabase:^(FMDatabase *db) { [db executeUpdate:sql]; }]; }]; // 删除备份表 [self.databaseQueue inDatabase:^(FMDatabase *db) { [db beginTransaction]; for (NSString* oldTableName in existsTables) { NSString* sql = [NSString stringWithFormat:@"DROP TABLE IF EXISTS %@", oldTableName]; [db executeUpdate:sql]; } [db commit]; }]; MMUserDefault.dbVersion = version_new; } else { MMUserDefault.dbVersion = version_new; } } - (NSDictionary*)generateMigrationInfosWithOldTables:(NSArray*)oldTables newTables:(NSArray*)newTables { NSMutableDictionary<NSString*, NSArray* >* migrationInfos = [NSMutableDictionary dictionary]; for (NSString* newTableName in newTables) { NSString* oldTableName = [NSString stringWithFormat:@"%@_bak", newTableName]; if ([oldTables containsObject:oldTableName]) { // 获取表数据库字段信息 NSArray* oldTableColumns = [self sqliteTableColumnsWithTableName:oldTableName]; NSArray* newTableColumns = [self sqliteTableColumnsWithTableName:newTableName]; NSArray* publicColumns = [self publicColumnsWithOldTableColumns:oldTableColumns newTableColumns:newTableColumns]; if (publicColumns.count > 0) { [migrationInfos setObject:publicColumns forKey:newTableName]; } } } return migrationInfos; } - (NSArray*)publicColumnsWithOldTableColumns:(NSArray*)oldTableColumns newTableColumns:(NSArray*)newTableColumns { NSMutableArray* publicColumns = [NSMutableArray array]; for (NSString* oldTableColumn in oldTableColumns) { if ([newTableColumns containsObject:oldTableColumn]) { [publicColumns addObject:oldTableColumn]; } } return publicColumns; } - (NSArray*)sqliteTableColumnsWithTableName:(NSString*)tableName { __block NSMutableArray<NSString*>* tableColumes = [NSMutableArray array]; [self.databaseQueue inDatabase:^(FMDatabase *db) { NSString* sql = [NSString stringWithFormat:@"PRAGMA table_info('%@')", tableName]; FMResultSet *rs = [db executeQuery:sql]; while ([rs next]) { NSString* columnName = [rs stringForColumn:@"name"]; [tableColumes addObject:columnName]; } }]; return tableColumes; } - (NSArray*)sqliteExistsTables { __block NSMutableArray<NSString*>* existsTables = [NSMutableArray array]; [self.databaseQueue inDatabase:^(FMDatabase *db) { NSString* sql = @"SELECT * from sqlite_master WHERE type='table'"; FMResultSet *rs = [db executeQuery:sql]; while ([rs next]) { NSString* tablename = [rs stringForColumn:@"name"]; [existsTables addObject:tablename]; } }]; return existsTables; } - (NSArray*)sqliteNewAddedTables { __block NSMutableArray<NSString*>* newAddedTables = [NSMutableArray array]; [self.databaseQueue inDatabase:^(FMDatabase *db) { NSString* sql = @"SELECT * from sqlite_master WHERE type='table' AND name NOT LIKE '%_bak'"; FMResultSet *rs = [db executeQuery:sql]; while ([rs next]) { NSString* tablename = [rs stringForColumn:@"name"]; [newAddedTables addObject:tablename]; } }]; return newAddedTables; }
相关推荐:
sql 2005 数据库升级2008 数据库 和2005 数据附加2008数据备份文
以上就是实例详解IOS 数据库升级数据迁移的详细内容,更多请关注php中文网其它相关文章!
……