【问题标题】:Android: what is wrong with my create table statement?Android:我的创建表语句有什么问题?
【发布时间】:2019-06-07 17:47:44
【问题描述】:

我的 SQLiteOpenHelper 的 onCreate 方法包含以下代码:

Log.d("mytag", "oncreate is called");
db.execSQL("CREATE TABLE TrainingSession (id INTEGER PRIMARY KEY, session_date TEXT, session_status TEXT)");
Log.d("mytag", "tables were created");

Logcat 输出仅包含第一个 Log.d:

oncreate is called

然后应用程序崩溃。我的 create table 语句有什么问题?

编辑

Logcat 实际上表示TrainingSession 表已经存在。但是,我的 onUpgrade 方法如下所示:

Log.d("mytag", "onupgrade is called");
db.execSQL("DROP TABLE IF EXISTS TrainingSet; DROP TABLE IF EXISTS TrainingSession;");
onCreate(db);

并且该方法的 Logcat 输出与预期的一样,该方法确实被调用:

onupgrade is called

如果调用了 onUpgrade 并删除了表,那么为什么 onCreate 说 TrainingSession 已经存在?

【问题讨论】:

  • "然后应用程序崩溃" -- 使用 Logcat 检查与您的崩溃相关的 Java 堆栈跟踪:stackoverflow.com/q/23353173/115145
  • 您的 CREATE TABLE 声明 AFAIK 没有任何问题。您可以尝试直接针对 SQLite 运行它以说服自己它是正确的。您的代码中一定还有其他问题。
  • 我实际上已经在我的 firefox SQLite 扩展中测试了 create 语句。它工作正常。但是为什么没有生成第二个输出?我不知道“使用 logcat 来检查 java 堆栈跟踪”是什么意思,我得用谷歌搜索一下。
  • 好吧,这很快:它说培训课程已经存在。我将编辑我的问题以放大正在运行的代码的图片。

标签: java android sqlite android-sqlite create-table


【解决方案1】:

来自https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase#execSQL(java.lang.String)

execSQL
在 API 级别 1 中添加
public void execSQL (String sql)
执行 不是 SELECT 或任何其他 SQL 语句的单个 SQL 语句 返回数据。
................................
参数 sql String:
要执行的 SQL 语句。
多个 不支持用分号分隔的语句。

所以execSql() 不支持用 ;分隔的多个语句
所以对每个语句执行多个execSql()

public static final String SQL_DELETE_TABLE1 = "DROP TABLE IF EXISTS TrainingSet"
db.execSQL(SQL_DELETE_TABLE1); 
public static final String SQL_DELETE_TABLE2 = "DROP TABLE IF EXISTS TrainingSession"
db.execSQL(SQL_DELETE_TABLE2);

【讨论】:

  • 我知道,我在构造函数中调用 getWritableDatabase 以进行测试。不过,您的粗体陈述并不正确。如果数据库不存在或您的数据库版本增加(因为 onupgrade 调用 oncreate),则调用 oncreate。您可以从 logcat 输出中看到正在调用 oncreate。所以请收回你的反对票。
  • 我没有投反对票。 如果你的数据库版本增加了这将触发onUpgrade()
  • 哦,我以为是你,对不起。是的,它会触发 onUpgrade。它会删除表(或者因为我收到此错误而不删除表 - 但我不知道为什么它不这样做,这就是这里的问题),然后调用 onCreate 来重新创建数据库。但是在 onCreate 中,应用程序崩溃,因为“trainingsession 已经存在!”。但是该表应该已在 onupgrade 中删除(并且从 logcat 中可以看到,确实调用了 onupgrade)。
  • 天哪,非常感谢 :) 我开始觉得我永远无法解决这个问题,而且没人知道出了什么问题。这就是问题的原因,现在一切都按预期工作!我永远不会假设您不能在 db.execSQL 想要的字符串中传递多个 SQL 语句。如果是这样,我会预料到某个地方会出现错误,可能是“无法传递多个语句。语句被删除”。无论如何,谢谢你!
【解决方案2】:

如果查询没问题,如果数据库结构发生变化,这些事情就会发生。

尝试:

选项1:添加其他sqlite数据库版本。

选项 2 :删除数据库并重新创建它。

选项 3:从手机应用信息屏幕中清除应用数据。

【讨论】:

  • 我在上面添加了信息和代码。该表已经存在,但正如您从我的代码中看到的那样,他应该在重新创建它们之前删除这些表。他们怎么还在那里?
猜你喜欢
  • 1970-01-01
  • 2011-01-17
  • 2018-12-04
  • 2010-09-19
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多