迁移房间数据库时有没有办法使用迁移期间计算的变量?

     2023-04-18     215

关键词:

【中文标题】迁移房间数据库时有没有办法使用迁移期间计算的变量?【英文标题】:Is there a way when Migrating a Room Database to use Variables that are calculated during the Migration? 【发布时间】:2021-06-17 00:26:30 【问题描述】:

我正在用 Java 编写一个 Android 应用程序,并且我已经更改了我的数据库,现在我想将它迁移到新版本,但为此我需要计算一些旧值,然后将它们插入其中一个新表进入数据库但是当我调用时

database.execSQL()

使用我的变量然后访问它们似乎没有设置它们,因为每个值都是 0。

这是不可能的,还是我只是错过了什么?

public void migrate(@NonNull SupportSQLiteDatabase database) 
             database.execSQL("CREATE TABLE 'season' ('id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
                    'spring' INTEGER DEFAULT 0, 'summer' INTEGER DEFAULT 0, 'autumn' INTEGER 
                    DEFAULT 0, 'winter' 
                    INTEGER DEFAULT 0, 'spook' INTEGER DEFAULT 0)");
            database.execSQL("INSERT INTO 'Clothes' (type_of_clothing,clothing_name,description,seasonId,in_laundry,TypeList) " +
                    "SELECT type_of_clothing,clothing_name,description,type_of_clothing,in_laundry,TypeList " +
                    "FROM ClothesNew");
            Cursor cursor = database.query("SELECT * FROM Clothes");
            Cursor secondCursor = database.query("SELECT * FROM ClothesSeason");
            ArrayList<Season> seasonsToBeAdded = new ArrayList<>();
            while (cursor.moveToNext()) 
                secondCursor.moveToNext();
                int Sid = cursor.getInt(0);
                String seasonString = secondCursor.getString(2);
                Season season = new Season(seasonString);
                int tempId = Sid;
                boolean isInList = false;
                for (Season tempSeason : seasonsToBeAdded) 
                    if (tempSeason.equals(season)) 
                        tempId = seasonsToBeAdded.indexOf(tempSeason);
                        isInList = true;
                        break;
                    
                
                if (!isInList) 
                    season.setId(seasonsToBeAdded.size());
                    tempId = season.getId();
                    seasonsToBeAdded.add(season);
                
                if (seasonsToBeAdded.size() == 0) seasonsToBeAdded.add(season);
                
                database.execSQL("UPDATE Clothes SET seasonId = :tempId WHERE uid = :Sid");
            

            int id, spring, summer, autumn, winter, spook;

            for (Season season : seasonsToBeAdded) 
                id = season.getId();
                spring = season.getSpring();
                summer = season.getSummer();
                autumn = season.getAutumn();
                winter = season.getWinter();
                spook = season.getSpook();
                database.execSQL("INSERT INTO season " +
                        "VALUES(:id, :spring, :summer, :autumn, :winter, :spook) ");
            
            Cursor otherCursor = database.query("SELECT * FROM season");
            ArrayList<Integer> springValues= new ArrayList<>();
            while (otherCursor.moveToNext()) 
                springValues.add(otherCursor.getInt(1));
            
        

当我查看存储在 springValues 中的值时,即使我在此查询中添加了正确的值,它们也都是 0

database.execSQL("INSERT INTO season " +
                 "VALUES(:id, :spring, :summer, :autumn, :winter, :spook) ");

我可以不在这里使用 :var 符号吗?

【问题讨论】:

【参考方案1】:

我建议使用 SQLiteDatabase Insert 便捷方法和 ContentValues 对象。

而不是:-

        for (Season season : seasonsToBeAdded) 
            id = season.getId();
            spring = season.getSpring();
            summer = season.getSummer();
            autumn = season.getAutumn();
            winter = season.getWinter();
            spook = season.getSpook();
            database.execSQL("INSERT INTO season " +
                    "VALUES(:id, :spring, :summer, :autumn, :winter, :spook) ");
        

您的代码可能是:-

    ContentValues cv = new ContentValues(); // Instantiate ContentValues object
    for (Season season : seasonsToBeAdded) 
        cv.clear();
        cv.put("`id`",season.getId());
        cv.put("`spring`",season.getSpring());
        cv.put("`summer`",season.getSummer());
        cv.put("`autumn`",season.getAutumn());
        cv.put("`winter`",season.getWinter());
        cv.put("`spook`",season.getSpook());
        database.insert("season",null,cv); //<<<< Recommended Uses the convenience Insert Method

请注意,列名不必像上面使用的那样用重音 `` 括起来。

以上代码为in-principal code,未经测试,可能存在一些错误。

如您所见,SQL 是为您构建的。 insert 方法返回插入行的 rowid(id 列),如果插入失败则返回 -1,您可能希望利用该值。

您可能还希望使用其他插入方法,例如insertWithOnConflict 例如database.insertWithOnConflict("season",null,cv,SQLiteDatabase.CONFLICT_IGNORE);

还建议通过使用适当的 SQLiteDatabase 事务处理方法来利用事务(请参阅beginTransaction)

还建议您对列名使用常量,以便在适当的位置对名称进行编码。列名错误的可能性很小。

【讨论】:

计算数据库实时数据时出现异常 - 迁移期间崩溃

】计算数据库实时数据时出现异常-迁移期间崩溃【英文标题】:Exceptionwhilecomputingdatabaselivedata-crashduringmigration【发布时间】:2019-10-2016:01:30【问题描述】:我使用的是cwac-saferoom1.0.4版一些设备在将应用程序更新到新版本后立即... 查看详情

在 Android 中使用房间数据库写入迁移的查询错误

】在Android中使用房间数据库写入迁移的查询错误【英文标题】:QueryerrortowritemigrationwithroomdatabaseinAndroid【发布时间】:2020-06-1304:59:42【问题描述】:我正在尝试在我的项目中迁移我的房间数据库,并为迁移编写查询。在现有表... 查看详情

由于房间中的唯一约束,数据库迁移失败

】由于房间中的唯一约束,数据库迁移失败【英文标题】:DatabaseMigrationFailedduetouniqueconstraintinroom【发布时间】:2018-05-2104:44:29【问题描述】:我在旧数据库中的一张表中有唯一约束。在迁移到房间时,我按照[link][1]上的说明创... 查看详情

有没有办法使用通配符迁移 BigQuery 表?

】有没有办法使用通配符迁移BigQuery表?【英文标题】:IsthereawaytomigrateBigQuerytablesbyusingwildcards?【发布时间】:2020-05-1014:04:13【问题描述】:我在BigQuery上有一组包含某种数据的表,我想通过我定义的JavaScript函数处理这些数据。J... 查看详情

仅向多个表的主键添加 @NonNull 注释的房间迁移

...:我正在将应用程序从定位sdk25升级到定位sdk29,我房间数据库中的所有表都有@PrimaryKey注释,但没有使用@NonNull注释.现在我的目标是sdk29,房 查看详情

有没有办法从 CloudKit 迁移数据?

】有没有办法从CloudKit迁移数据?【英文标题】:IsthereanywaytomigratedatafromCloudKit?【发布时间】:2017-11-0913:44:22【问题描述】:我想构建一个简单的仅适用于iOS的社交应用。我还没有办法通过这个应用程序获利,所以我想让这个项... 查看详情

向现有房间数据库添加一列,同时使用房间版本 2.4.0-alpha01 中提供的当前自动迁移功能

】向现有房间数据库添加一列,同时使用房间版本2.4.0-alpha01中提供的当前自动迁移功能【英文标题】:Addacolumntoexistingroomdatabasewhilstusingthecurrentauto-migrationfeatureavailableinroomversion2.4.0-alpha01【发布时间】:2021-11-2505:39:21【问题描述... 查看详情

在 Flyway 中编写 Java 迁移时,有没有办法使用 HibernateTemplate/JPATemplate?

...注释配置的hibernate3的项目,并且正在寻找与开发同步的数据库 查看详情

(Android) 房间数据库迁移不会改变数据库

】(Android)房间数据库迁移不会改变数据库【英文标题】:(Android)Roomdatabasemigrationdoesn\'tchangedatabase【发布时间】:2018-11-1110:48:54【问题描述】:我需要更新SQLite-Database,所以我创建了一个迁移。在逐步调试此迁移时,没有错误,... 查看详情

迁移期间 Laravel 未知数据库错误

】迁移期间Laravel未知数据库错误【英文标题】:Laravelunknowndatabaseerrorduringmigration【发布时间】:2019-11-1810:23:42【问题描述】:我无法在Homestead/Vagrant盒子中运行Laravel迁移。这样的问题还有很多,但似乎没有一个适合我的答案。... 查看详情

.env 文件中的环境变量在 django、heroku 的本地迁移期间不可用

】.env文件中的环境变量在django、heroku的本地迁移期间不可用【英文标题】:Environmentalvariablesfrom.envfilenotavailableduringlocalmigrationsindjango,heroku【发布时间】:2016-11-2102:06:15【问题描述】:我一直在Heroku上进行开发,使用config变量来... 查看详情

生成 Android 房间迁移的最佳方法是啥?

...在POCO对象中指定您想要的更改。添加新迁移时,它会在数据库和 查看详情

耳部部署期间的飞路迁移

...】:如果Flyway可以在部署.ear工件(JBoss4.2)期间迁移我们的数据库,我们会很高兴。如果出现任何问题,它应该中止。使用mvnflyway:migrate的Flyway可以工作,但对于持续集成和生产环境(可能还有其他下载新SNAPSHOTS的环境),将数据... 查看详情

有没有办法将数据从核心数据迁移到在线数据库?

】有没有办法将数据从核心数据迁移到在线数据库?【英文标题】:IsthereaawaytomigratedatafromCoreDatatoOnlineDatabase?【发布时间】:2011-11-2900:13:04【问题描述】:我的应用目前使用核心数据。我创建了一个新版本的应用程序,它完全基... 查看详情

房间迁移:“没有这样的表:room_table_modification_log”

】房间迁移:“没有这样的表:room_table_modification_log”【英文标题】:Roommigration:"nosuchtable:room_table_modification_log"【发布时间】:2018-10-2611:54:51【问题描述】:房间1.1.0版本。我在迁移后第一次运行时遇到此错误。如果我... 查看详情

如何在数据迁移期间使用 mongoose 设置 updatedAt 时间戳

】如何在数据迁移期间使用mongoose设置updatedAt时间戳【英文标题】:HowdoIsettheupdatedAttimestampusingmongooseduringadatamigration【发布时间】:2017-01-1703:07:57【问题描述】:我正在进行从MSSQL到MongoDB的数据迁移。我正在使用猫鼬,并在我的... 查看详情

具有唯一索引的房间数据库迁移问题

】具有唯一索引的房间数据库迁移问题【英文标题】:RoomDatabaseMigrationIssuewithUniqueIndex【发布时间】:2019-07-2309:12:17【问题描述】:我正在尝试升级我的数据库版本,在上一个版本中,该表具有在迁移室创建的唯一索引给我以下... 查看详情

Android 房间迁移测试失败,但没有任何改变

】Android房间迁移测试失败,但没有任何改变【英文标题】:AndroidRoomMigrationtestfails,althoughnothingchanged【发布时间】:2020-09-1516:58:04【问题描述】:我正在尝试测试Room迁移,但测试总是失败。模型甚至没有变化。我只增加了版本号... 查看详情