【问题标题】:Android executeSQL not working (INSERT INTO TABLE2 SELECT * FROM TABLE1)Android executeSQL 不工作(INSERT INTO TABLE2 SELECT * FROM TABLE1)
【发布时间】:2012-06-08 10:19:10
【问题描述】:

我必须将数据从一个表移到另一个表。 新表将与旧表一样,但没有约束(冲突替换),因此列是相同的。

这是我要做的查询:INSERT INTO TABLE2 SELECT * FROM TABLE1

我遇到了一个大问题,因为我认为我无法执行这种查询:

db.execSQL("INSERT INTO " + Tables.TRACKS + "_2  SELECT * FROM " + Tables.TRACKS );

execSQL 失败并出现此错误 (db onUpgrade):

06-04 12:25:50.000: D/SqliteDatabaseCpp(17817): Registering sqlite logging func: /data/data/com.musixmatch.android.lyrify/databases/library.db
06-04 12:25:50.000: D/SqliteDatabaseCpp(17817): DB info: open db, path = /data/data/com.musixmatch.android.lyrify/databases , key = lafvYvq, flag = 6, file size = 101376
06-04 12:25:50.000: D/SqliteDatabaseCpp(17817): DB info: path = /data/data/com.musixmatch.android.lyrify/databases , key = lafvYvq, handle: 0x1bd8bd8, type: w, r/w: (0,1), mode: delete, disk free size: 1243 M


06-04 12:25:50.010: D/SqliteDatabaseCpp(17817): DB info: close db, path = /data/data/com.musixmatch.android.lyrify/databases , key = lafvYvq, handle = 0x1bd8bd8, type = w, r/w = (0, 0)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817): Couldn't open library.db for writing (will try read-only):
06-04 12:25:50.030: E/SQLiteOpenHelper(17817): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:95)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:2008)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1948)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at com.designfuture.music.provider.MusicDatabase.alterTrackFragmentForFileIDSupport(MusicDatabase.java:316)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at com.designfuture.music.provider.MusicDatabase.onUpgrade(MusicDatabase.java:242)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:188)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:249)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at com.designfuture.music.provider.MusicProvider.query(MusicProvider.java:199)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.content.ContentProvider$Transport.query(ContentProvider.java:189)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.content.ContentResolver.query(ContentResolver.java:315)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.content.AsyncQueryHandler$WorkerHandler.handleMessage(AsyncQueryHandler.java:94)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.os.Handler.dispatchMessage(Handler.java:99)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.os.Looper.loop(Looper.java:156)
06-04 12:25:50.030: E/SQLiteOpenHelper(17817):  at android.os.HandlerThread.run(HandlerThread.java:60)
06-04 12:25:50.030: D/SqliteDatabaseCpp(17817): DB info: open db, path = /data/data/com.musixmatch.android.lyrify/databases , key = lafvYvq, flag = 1, file size = 101376
06-04 12:25:50.030: D/SqliteDatabaseCpp(17817): DB info: path = /data/data/com.musixmatch.android.lyrify/databases , key = lafvYvq, handle: 0x1bec760, type: r, r/w: (1,0), mode: delete, disk free size: 1243 M
06-04 12:25:50.030: D/SqliteDatabaseCpp(17817): DB info: close db, path = /data/data/com.musixmatch.android.lyrify/databases , key = lafvYvq, handle = 0x1bec760, type = r, r/w = (0, 0)
06-04 12:25:50.040: W/AsyncQuery(17817): Exception thrown during handling EVENT_ARG_QUERY
06-04 12:25:50.040: W/AsyncQuery(17817): android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 7 to 9: /data/data/com.musixmatch.android.lyrify/databases/library.db
06-04 12:25:50.040: W/AsyncQuery(17817):    at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:262)
06-04 12:25:50.040: W/AsyncQuery(17817):    at com.designfuture.music.provider.MusicProvider.query(MusicProvider.java:199)
06-04 12:25:50.040: W/AsyncQuery(17817):    at android.content.ContentProvider$Transport.query(ContentProvider.java:189)
06-04 12:25:50.040: W/AsyncQuery(17817):    at android.content.ContentResolver.query(ContentResolver.java:315)
06-04 12:25:50.040: W/AsyncQuery(17817):    at android.content.AsyncQueryHandler$WorkerHandler.handleMessage(AsyncQueryHandler.java:94)
06-04 12:25:50.040: W/AsyncQuery(17817):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-04 12:25:50.040: W/AsyncQuery(17817):    at android.os.Looper.loop(Looper.java:156)
06-04 12:25:50.040: W/AsyncQuery(17817):    at android.os.HandlerThread.run(HandlerThread.java:60)

我认为这是因为我在查询中添加了一个 SELECT。这来自 Android 文档:http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL%28java.lang.String%29

执行不是 SELECT 或任何其他 SQL 的单个 SQL 语句 返回数据的语句。

如果我使用

db.rawQuery( "INSERT INTO " + Tables.TRACKS + "_2  SELECT * FROM " + Tables.TRACKS, null  );

它执行没有错误,但它不做任何事情。我认为这是因为 rawQuery 用于执行 SELECT 查询并且不会写入数据库。

更新:如果我使用普通查询选择所有记录,然后通过循环将它们插入到新表中,一切正常,但这不是优化的方式,我不想一个缓慢升级的应用程序

UPDATE2

这些是这两个表之间的唯一区别:

新表有 3 个新的字符串列,它们可以为空 新表不会有旧表具有的唯一( ON CONFLICT REPLACE )约束

两个表都有这个字段:BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT"。我必须从插入中排除该字段吗?还要记住第二个平板电脑在升级时是空的(我正在升级时创建它)

那么我该怎么做才能执行一个需要和我同时读写的查询呢?

【问题讨论】:

  • 您可以编辑您的问题以显示您遇到的错误吗?
  • 更新了最初的帖子
  • 您可以发布用于创建两个表的CREATE TABLE 语句吗?插入时遇到约束违规。此外,db.rawQuery("INSERT .. 不会做任何事情 - 总是使用execSQL 进行插入、更新和删除。
  • 新表有 3 个新字段(可以为空),它不会有唯一约束

标签: android sqlite


【解决方案1】:

由于您没有发布表格布局,让我们从以下内容开始:

CREATE TABLE TABLE1 (
   _id INTEGER PRIMARY KEY,
   value1 TEXT,
   value2 TEXT
);

CREATE TABLE TABLE2 (
   _id INTEGER PRIMARY KEY,
   value2 TEXT,
   value1 TEXT,
   value3 TEXT,
   value4 TEXT,
   value5 TEXT
);

要将TABLE1 中的值正确插入TABLE2,您必须考虑到顺序和列数重要 并且必须匹配(& 如果您有主键,最好省略它们从插入和选择语句 - 不要到处复制这样的东西)。

INSERT INTO TABLE2 (value1, value2) SELECT value1, value2 FROM TABLE1

【讨论】:

  • 所以最好的方法也是不要省略要选择的列和插入的顺序。发布后我会试一试,我会回复你的:)
  • 除非表完全相同(在这种情况下 - 为什么要复制?)您应该始终指定您的 INSERT 和 SELECT 列以相互匹配。
  • 我想删除 ON CONFLICT REPLACE 并且 sqlite3 不允许您更改表以删除该约束。因此,唯一的方法是创建一个新表,移动数据,删除旧表,将新表重命名为旧表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多