引起:android.database.sqlite.SQLiteException:没有这样的表:(代码1)Android

时间:2014-07-08 14:14:40

标签: android android-sqlite

我们的应用程序中有一个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

16 个答案:

答案 0 :(得分:28)

问题是因为某些设备正在升级您的应用,因此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);

}

答案 1 :(得分:13)

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

1)设置&gt;应用程序管理器

2)选择App

3)清除数据

4)卸载App

立即从Android Studio运行应用

希望这项工作正常

答案 2 :(得分:7)

另一种可能的解决方案是从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"

答案 3 :(得分:6)

发生此错误因为您没有使用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 :(得分:1)

即使您为几个表和升级的数据库编写了代码,您的应用程序也会崩溃。您需要为每个表创建数据库更改升级DATABASE_VERSION

如果您的DatabaseHelper类(read this)很少,则必须将此方法添加到数据库帮助器中:

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

如果您使用GreenDao并收到此错误,请确保您取消应用程序并重试。这解决了我的问题

答案 8 :(得分:0)

假设您使用数据库版本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值。

答案 9 :(得分:0)

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

答案 10 :(得分:0)

像这样在主类中初始化副本数据库或数据库助手 数据库助手=新数据库(this); helper.execute(sqliteobj)

答案 11 :(得分:0)

这是解决此问题的另一种方法,有时开发人员不知道列名与其结尾之间没有空格,例如KEY_ADDRESS,这是错误的方法,在逗号和属性名之间使用空格

答案 12 :(得分:0)

尝试删除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");
            }

答案 13 :(得分:0)

当我为应用程序创建更新时,我遇到了同样的问题。 谷歌文档仅在首次安装应用程序时才调用SQLiteOpenHelper的onCreate()。 因此,如果要添加表,则需要增加数据库版本并添加

onUpgrade() { your_table.create(database) }

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

答案 14 :(得分:0)

我的情况不同:

我正在使用Room的{​​{3}}在几个数据库文件之间切换,要实现这一点,需要首先删除数据库,然后重新创建它以与其他数据库文件一起加载。

在删除过程中,我从数据库中观察到的LiveData产生了 SQLiteException: no such table ,这当然是合乎逻辑的,因为LiveData感觉到底层数据被更改,并尝试获取新数据,并发现表已消失。

要解决此问题:要么使用常规数据(不使用LiveData),要么停止观察LiveData,然后在成功创建数据库后再次观察它。 >

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

答案 15 :(得分:-1)

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