【问题标题】:Caused by: android.database.sqlite.SQLiteException: no such table: (code 1) Android引起:android.database.sqlite.SQLiteException:没有这样的表:(代码1)Android
【发布时间】:2014-07-08 14:14:39
【问题描述】:

我们的应用程序中有一个 sqlite 数据库。它适用于所有用户,但很少有人遇到Caused by: android.database.sqlite.SQLiteException: no such table: generalSettings (code 1): , while compiling: select * from generalSettings 错误。

下面是我创建数据库和错误日志的 sqlite 助手类。在assert/Master.db 我们有表格generalSettings。但是在将其复制到设备后,该表丢失了。这只发生在少数用户身上。我搜索了解决方案,但找不到确切的解决方案。请团队帮我解决这个问题。

代码:

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;

import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.util.Log;

public class InstallDB extends SQLiteOpenHelper {
    Context ctx;

    String DBNAME;
    String DBPATH;
    Modules modObj = new Modules();

    public InstallDB(Context context, String name) {
        super(context, name, null, 1);
        this.ctx = context;
        this.DBNAME = name;

        this.DBPATH = this.ctx.getDatabasePath(DBNAME).getAbsolutePath();
        Log.e("Path 1", DBPATH);

    }

    public void createDataBase() {

        boolean dbExist = checkDataBase();

        SQLiteDatabase db_Read = null;

        if (!dbExist) {
            synchronized (this) {

                db_Read = this.getReadableDatabase();
                Log.e("Path 2", this.getReadableDatabase().getPath());
                db_Read.close();

                copyDataBase();
                Log.v("copyDataBase---", "Successfully");
            }

            // try {

            // } catch (IOException e) {
            // throw new Error("Error copying database");
            // }
        }
    }

    private boolean checkDataBase() {

        SQLiteDatabase checkDB = null;

        try {
            String myPath = DBPATH;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READWRITE);
        } catch (Exception e) {
            Log.i("SQLite Error", "database does't exist yet.");
        }

        if (checkDB != null) {
            checkDB.close();
        }

        return checkDB != null ? true : false;
    }

    private void copyDataBase() {

        try {
            InputStream myInput = ctx.getAssets().open(DBNAME);
            String outFileName = DBPATH;

            OutputStream myOutput = new FileOutputStream(outFileName);

            byte[] buffer = new byte[1024 * 3];

            int length = 0;

            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }

            myOutput.flush();
            myOutput.close();
            myInput.close();
        } catch (Exception e) {
            Modules.stacTaceElement = e.getStackTrace();

            StringWriter stackTrace1 = new StringWriter();
            e.printStackTrace(new PrintWriter(stackTrace1));
            System.err.println(stackTrace1);

            Intent send = new Intent(Intent.ACTION_SENDTO);
            String uriText;

            uriText = "mailto:test@test.com"
                    + "&subject=Error Report"
                    + "&body="
                    + stackTrace1.toString();

            uriText = uriText.replace(" ", "%20");
            Uri uri = Uri.parse(uriText);

            send.setData(uri);
            ctx.startActivity(Intent.createChooser(send, "Send mail..."));
            // TODO: handle exception
        }

    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

错误日志:

java.lang.RuntimeException: Unable to start activity ComponentInfo{palmagent.FidelityAgent.Two/palmagent.FidelityAgent.Two.PassNew}: android.database.sqlite.SQLiteException: no such table: generalSettings (code 1): , while compiling: select * from generalSettings
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2269)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5102)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteException: no such table: generalSettings (code 1): , while compiling: select * from generalSettings
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
at palmagent.FidelityAgent.Two.masterDatabase.selectquery(masterDatabase.java:59)
at palmagent.FidelityAgent.Two.Modules.checkDatabase(Modules.java:28825)
at palmagent.FidelityAgent.Two.PassNew$LoaduserDetails.onPreExecute(PassNew.java:140)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
at android.os.AsyncTask.execute(AsyncTask.java:535)
at palmagent.FidelityAgent.Two.PassNew.onCreate(PassNew.java:120)
at android.app.Activity.performCreate(Activity.java:5248)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2173)
... 11 more

【问题讨论】:

  • 您是否正在将已部署的数据库副本写入 Android 将创建的数据库?我认为这是一个坏主意,因为 Android 在数据库本身中保存了一些私有数据。
  • @brummfondel - 我们在 Db 中有 10 个表和一些静态数据。所以创建数据库需要很长时间。所以我们复制了Android中的数据库。请告诉我最好的方法。
  • 在某些设备和模拟器上测试我的应用程序后,我遇到了同样的问题stackoverflow.com/questions/24406326/no-such-table-in-api-2-2

标签: android android-sqlite


【解决方案1】:

问题是因为一些设备正在升级你的应用程序,所以checkDataBase()返回true,所以你没有调用copyDataBase()。因此,您使用的是以前没有 generalSettings 表的数据库。 要解决此问题,请尝试:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(newVersion>oldVersion)
  copyDatabase();
}

并更新你的构造函数:

public InstallDB(Context context, String name) {
    super(context, name, null, DB_VERSION); 
    // DB_VERSION is an int,update it every new build

    this.ctx = context;
    this.DBNAME = name;
    this.DBPATH = this.ctx.getDatabasePath(DBNAME).getAbsolutePath();
    Log.e("Path 1", DBPATH);

}

【讨论】:

  • 如果此答案解决了您的问题,请将其标记为正确答案。
  • 可以调用 OnUpgrabde 的 newVersion 实际上低于 oldVersion 吗?
【解决方案2】:

花了几个小时后,我得到了这个解决方案:

1) 设置 > 应用程序管理器

2) 选择应用程序

3) 清除数据

4) 卸载应用程序

现在从 Android Studio 运行应用程序

希望一切正常

【讨论】:

  • 这仅适用于临时测试,但不适用于旧版本的用户
【解决方案3】:

出现此错误是因为您没有使用 DATABASE_VERSION

public class DatabaseHelper extends SQLiteOpenHelper {
    private static SQLiteDatabase sqliteDb;

    private static DatabaseHelper instance;

    private static final int DATABASE_VERSION = 1;

每次在数据库中进行更改时增加您的版本只需将 DATABASE_VERSION 增加 +1..

【讨论】:

    【解决方案4】:

    另一种可能的解决方案是从 Android 模拟器中卸载一个应用程序,然后再次运行它。

    如果您只想删除应用程序:

    1.Start the emulator.
    2.Open the Android settings app.
    3.Select "Applications" (Called "Apps" on Android 4.0 or higher)
    4.Select "Manage Applications" (Only on Android 3.2 or lower)
    5.Select the application you want to uninstall.
    6.Click "Uninstall"
    

    【讨论】:

    • 当您在开发过程中更改数据库结构或命名时,这很有意义。如果您在版本之间更改它,您需要为用户处理升级并且不能告诉他们手动重新安装应用程序;-)
    【解决方案5】:

    假设如果您使用数据库版本 1 运行应用程序,那么如果您更改表结构或添加新表,则必须将数据库版本增加到 2,如果您对其进行更多更改,则必须进一步增加。

    public class AppDatabase extends SQLiteOpenHelper {
    
        // Database Name
        private static final String DATABASE_NAME = "myDatabase";
    
        // Database Version
        private static final int DATABASE_VERSION = 1;    
    
        public AppDatabase(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
    }
    

    如果进行了任何更改,请增加此 DATABASE_VERSION 值。

    【讨论】:

      【解决方案6】:

      即使您为少数表编写代码并升级了数据库,您的应用也会崩溃。您要做的是为每个表创建数据库更改升级DATABASE_VERSION

      如果您的 DatabaseHelper 类很少 (read this),则必须将此方法添加到您的 db helper:

      @Override
      public void onOpen(SQLiteDatabase db) {
          onCreate(db);
      }
      

      【讨论】:

        【解决方案7】:

        更新 DATABASE_VERSION 并卸载应用。现在运行应用程序。

        【讨论】:

        • 是的@paul 这样我们可以管理,但是如果我们不想卸载应用程序,那么在这种情况下我们应该怎么做。
        【解决方案8】:

        如果您在使用 GreenDao 时遇到此错误,请确保您正在卸载应用程序并重试。这解决了我的问题

        【讨论】:

          【解决方案9】:

          这是一个升级例外。确保您在以前的数据库中有该表。如果没有,请创建它。 PS:如果您是新开发此应用程序,请从您的模拟器或设备上卸载它并重新安装。但不推荐,因为数据不会丢失。

          【讨论】:

            【解决方案10】:

            1.更改您的数据库版本 或者 首先在模拟器或手机中卸载您的应用程序并重新安装。 我以这种方式认为您的问题将得到解决。

            【讨论】:

              【解决方案11】:

              就我而言,我更改了我的数据库名称及其对我的工作

              【讨论】:

                【解决方案12】:

                请像这样在主类中初始化复制数据库或数据库助手 数据库助手 = 新数据库(此); helper.execute(sqliteobj)

                【讨论】:

                  【解决方案13】:

                  这是解决这个问题的另一种方法,有些时候开发人员不知道列名和它的结尾之间没有空格,比如 KEY_ADDRESS,这是错误的方法使用逗号和属性名称之间的空格

                  【讨论】:

                    【解决方案14】:

                    尝试删除 getReadableDatabase

                     if (!dbExist) {
                                synchronized (this) {
                    
                                    db_Read = this.getReadableDatabase();
                                    Log.e("Path 2", this.getReadableDatabase().getPath());
                                    db_Read.close();
                    
                                    copyDataBase();
                                    Log.v("copyDataBase---", "Successfully");
                                }
                    

                     if (!dbExist) {
                                synchronized (this) {
                    
                                    //db_Read = this.getReadableDatabase();
                                  //  Log.e("Path 2", this.getReadableDatabase().getPath());
                                  //  db_Read.close();
                    
                                    copyDataBase();
                                    Log.v("copyDataBase---", "Successfully");
                                }
                    

                    【讨论】:

                    • 记得在运行前删除已安装的应用程序。
                    【解决方案15】:

                    当我为应用程序创建更新时,我遇到了同样的问题。 根据谷歌文档,来自 SQLiteOpenHelper 的 onCreate() 仅在第一次安装应用程序时被调用。 所以如果你想添加一个表,你需要增加数据库版本并添加

                    onUpgrade() { your_table.create(database) }
                    

                    @Override public void onUpgrade(final SQLiteDatabase database, final int oldVersion, final int newVersion) { YourTable.onCreate(database); }

                    【讨论】:

                      【解决方案16】:

                      我的情况不同:

                      我正在使用RoomcreateFromAsset()在几个数据库文件之间切换,实现这一点需要首先删除数据库并重新创建它以与另一个数据库文件一起加载..

                      在删除过程中,我从数据库中观察到的LiveData 引发了SQLiteException: no such table,当然这是合乎逻辑的,因为LiveData 感知到基础数据已更改,并尝试去获取新的数据,发现表没了。

                      解决此问题:要么使用普通数据(无LiveData),要么停止观察LiveData,等数据库重建成功后重新观察。

                      注意:在不删除数据库文件的情况下,Room 会继续使用旧数据库文件的缓存版本。

                      【讨论】:

                        【解决方案17】:

                        试试这个解决方案,这个对我有用:

                        1. 选择应用程序

                        2. 清除缓存

                        3. 清除数据

                        4. 卸载应用

                        然后从 Android Studio 运行应用程序

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2018-12-20
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2016-08-23
                          • 1970-01-01
                          相关资源
                          最近更新 更多