ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

ORMLite在Android上将表从一个数据库插入另一个数据库的问题

2019-05-29 09:13:27  阅读:313  来源: 互联网

标签:database android sqlite insert ormlite


我正在从服务器下载SQLite数据库文件到用户的Android设备.下载后,我使用下载的数据库插入或替换本地数据库中的一些表.我使用ORMLite 4.47.

首先,我将数据库文件附加到DatabaseConnection:

DatabaseConnection con = null;
con = conSrc.getReadWriteConnection();
con.executeStatement("attach database '" + localDatabase.getAbsolutePath() + "' as '" + localDb + "'", DatabaseConnection.DEFAULT_RESULT_FLAGS);
con.executeStatement("attach database '" + downloadedDatabase.getAbsolutePath() + "' as '" + remoteDb + "'", DatabaseConnection.DEFAULT_RESULT_FLAGS);

附加数据库后,我创建以下查询以从下载的数据库(remoteDb)复制到本地数据库(localDb):

INSERT OR REPLACE INTO localDb.table_items (createdAt_device, updatedAt_device, _id, column_1, column_2, column_3, column_4, column_5, column_6) SELECT createdAt_device, updatedAt_device, _id, column_1, column_2, column_3, column_4, column_5, column_6 FROM remoteDb.table_items

然后,我从ORMLite执行以下函数:

con.executeStatement(query, flags); 

该功能在Android 4.1版(使用SQLite 3.7.11)及更高版本上运行良好.但是我在Android 4.0和4.0.3(使用SQLite 3.7.4)上遇到以下错误:

09-13 15:51:19.852: E/com.example.controller(1028): java.sql.SQLException: Problems executing INSERT OR REPLACE INTO localDb.table_items (createdAt_device, updatedAt_device, _id, column_1, column_2, column_3, column_4, column_5, column_6) SELECT createdAt_device, updatedAt_device, _id, column_1, column_2, column_3, column_4, column_5, column_6 FROM remoteDb.table_items Android statement: INSERT OR REPLACE INTO localDb.table_items (createdAt_device, updatedAt_device, _id, column_1, column_2, column_3, column_4, column_5, column_6) SELECT createdAt_device, updatedAt_device, _id, column_1, column_2, column_3, column_4, column_5, column_6 FROM remoteDb.table_items
09-13 15:51:19.852: E/com.example.controller(1028):     at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.j256.ormlite.android.AndroidCompiledStatement.execSql(AndroidCompiledStatement.java:185)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.j256.ormlite.android.AndroidDatabaseConnection.executeStatement(AndroidDatabaseConnection.java:134)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller$DatabaseTransferHandler.executeDatabaseTransfers(contoller.java:763)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller$DatabaseTransferHandler.access$0(contoller.java:740)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller.transferTables(contoller.java:494)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller.addElement(contoller.java:132)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller.addOrRemoveElements(contoller.java:109)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller.addElements(contoller.java:147)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller.download(contoller.java:254)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller.access$3(controller.java:204)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller$2.doInBackground(contoller.java:468)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.example.controller$2.doInBackground(contoller.java:1)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
09-13 15:51:19.852: E/com.example.controller(1028):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
09-13 15:51:19.852: E/com.example.controller(1028):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
09-13 15:51:19.852: E/com.example.controller(1028):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
09-13 15:51:19.852: E/com.example.controller(1028):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
09-13 15:51:19.852: E/com.example.controller(1028):     at java.lang.Thread.run(Thread.java:856)
09-13 15:51:19.852: E/com.example.controller(1028): Caused by: android.database.sqlite.SQLiteDatabaseLockedException: database is locked
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteStatement.native_executeSql(Native Method)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:90)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1899)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1839)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:661)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:576)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:247)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:84)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1899)
09-13 15:51:19.852: E/com.example.controller(1028):     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1889)
09-13 15:51:19.852: E/com.example.controller(1028):     at com.j256.ormlite.android.AndroidCompiledStatement.execSql(AndroidCompiledStatement.java:183)
09-13 15:51:19.852: E/com.example.controller(1028):     ... 18 more

我怎么解决这个问题?是否有更好的方法可以将大量信息下载到设备?

解决方法:

我是这个问题的作者的同事,我设法找到一种方法来避免这个问题.我想我会在这里发布,以防其他人遇到同样的问题.

具有该特定操作系统版本的Android设备似乎对这一系列Ormlite命令有问题:

DatabaseConnection con = null;
con = conSrc.getReadWriteConnection();
con.executeStatement("attach database '" + localDatabase.getAbsolutePath() + "' as '" + localDb + "'", DatabaseConnection.DEFAULT_RESULT_FLAGS);
con.executeStatement("attach database '" + downloadedDatabase.getAbsolutePath() + "' as '" + remoteDb + "'", DatabaseConnection.DEFAULT_RESULT_FLAGS);

我不知道这是由这些设备上预装的SQLite3版本引起的,还是由其他原因造成的.

现在我们可以避免这种情况,因为我们可以(幸运的是)完全避免在这种情况下使用Ormlite. SQLite语句“ATTACH DATABASE”不需要在DatabaseConnection实例上执行 – 它可以在本地数据库文件上执行.所以不是前一个块,只需要这个语句:

db.execSQL("ATTACH DATABASE '" + tempDb.getAbsolutePath() + "' AS '" + remoteDb + "'");

其中db是本地数据库的SQLiteDatabase实例.
SQLite documentation指出:

“The ATTACH DATABASE statement adds another database file to the current database connection.”

这就是不需要DatabaseConnection实例的原因.

标签:database,android,sqlite,insert,ormlite
来源: https://codeday.me/bug/20190529/1176780.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有