SQLite数据库在创建时崩溃

时间:2018-12-29 23:53:22

标签: sqlite android-studio

我正在设置一个应用程序,该应用程序在MainActivity中接收来自用户的信息,然后进行传输,以便SecondActivity在视图列表中显示信息。

我试图寻找导致问题的主要因素,但我发现它是数据库生成器,找不到导致该问题的原因。

public class HelperDB extends SQLiteOpenHelper{

    public static final String TABLE_CONTACT="Contact";
    public static final String TABLE_USER = "User";

    String strCreate, strDelete;

    private static final String DATABASE_NAME = "db.db";
    private static final int DATABASE_VERSION = 1;

    public HelperDB(Context context) {

        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        strCreate="CREATE TABLE "+TABLE_USER;
        strCreate+= " (_id INTEGER PRIMARY KEY AUTOINCRENEMT,";
        strCreate+= " "+NAME+" TEXT,";
        strCreate+= " "+AGE+" INTEGER";
        strCreate+= ");";
        db.execSQL(strCreate);

        strCreate="CREATE TABLE "+TABLE_CONTACT;
        strCreate+= " (_id INTEGER PRIMARY KEY AUTOINCRENEMT,";
        strCreate+=" "+PHONE+" TEXT,";
        strCreate+=" "+EMAIL+" TEXT,";
        strCreate+=" "+IDENTITY+" TEXT";
        strCreate+=");";
        db.execSQL(strCreate);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    strDelete="DROP TABLE IF EXISTS "+TABLE_USER;
    db.execSQL(strDelete);
    strDelete="DROP TABLE IF EXISTS "+TABLE_CONTACT;
    db.execSQL(strDelete);

    onCreate(db);
    }
}

当我在MainActivity上创建HelperDB时,它在OnCreate部分插入的部分崩溃:-

     hlp=new HelperDB(this);
     db=hlp.getWritableDatabase();
     db.close();

当我删除HelperDB时,应用程序继续崩溃,该应用程序运行正常。请帮我找到解决方案。

1 个答案:

答案 0 :(得分:0)

您使用了错误的关键字。 AUTOINCRENEMT 应该是 AUTOINCREMENT (两者都使用)。

但是,建议您不要编写AUTOINCREMENT代码,因为它效率低下,几乎绝对不需要。按照:-SQLite Autoincrement

其中包括:-

  

摘要

     

AUTOINCREMENT关键字强加了额外的CPU,内存,磁盘空间和磁盘I / O开销,如果不严格,应避免使用   需要。通常不需要。

     

在SQLite中,类型为INTEGER PRIMARY KEY的列是该变量的别名。   ROWID(在WITHOUT ROWID表中除外)始终为64位带符号   整数。

     

在INSERT上,如果ROWID或INTEGER PRIMARY KEY列不是   明确给定一个值,那么它将自动用   未使用的整数,通常比当前最大的ROWID多一   采用。不论AUTOINCREMENT是否为真   使用了关键字。

     

如果在INTEGER PRIMARY KEY之后出现AUTOINCREMENT关键字,则表明   更改自动ROWID分配算法以防止重用   数据库生命周期内的ROWID数量。换句话说,   AUTOINCREMENT的目的是防止ROWID的重用   先前删除的行。

使用column_name INTEGER PRIMARY KEY实际上是相同的,也就是说,在插入一行而未为 _id 列指定值的情况下,系统会为其指定一个唯一的数字,该数字通常会增加1(无论是否启用AUTOINCREMENT,都无法保证。)

  • AUTOINCREMENT所做的所有事情都是要确保此数字大于迄今为止使用的最大数字,但要付出一定的代价。无论如何,直到添加9223372036854775807行时,情况才会如此:-
  • 如果对AUTOINCREMENT进行了编码,则会发生SQLITE_FULL例外。
  • 如果未对AUTOINCREMENT进行编码,则尝试分配未使用的号码。
  • 但是,使用AUTOINCREMENT时,将涉及第二个系统表 sqlite_sequence 。这样会存储使用次数最多的数字,因此该值应大于最大的 rowid 或sqlite_sequqnce表中相应行的值+ 1,而不是最大的 rowid + 1。
    • 请注意“ column_name INTEGER PRIMARY KEY”(带有或不带有AUTOINCREMENT的列将列定义为 rowid 列的别名,该列通常是隐藏的列)。

修复(建议)

因此,以下是建议的修复方法:-

public class HelperDB extends SQLiteOpenHelper{

    public static final String TABLE_CONTACT="Contact";
    public static final String TABLE_USER = "User";

    String strCreate, strDelete;

    private static final String DATABASE_NAME = "db.db";
    private static final int DATABASE_VERSION = 1;

    public HelperDB(Context context) {

        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        strCreate="CREATE TABLE "+TABLE_USER;
        strCreate+= " (_id INTEGER PRIMARY KEY,";
        strCreate+= " "+NAME+" TEXT,";
        strCreate+= " "+AGE+" INTEGER";
        strCreate+= ");";
        db.execSQL(strCreate);

        strCreate="CREATE TABLE "+TABLE_CONTACT;
        strCreate+= " (_id INTEGER PRIMARY KEY,";
        strCreate+=" "+PHONE+" TEXT,";
        strCreate+=" "+EMAIL+" TEXT,";
        strCreate+=" "+IDENTITY+" TEXT";
        strCreate+=");";
        db.execSQL(strCreate);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    strDelete="DROP TABLE IF EXISTS "+TABLE_USER;
    db.execSQL(strDelete);
    strDelete="DROP TABLE IF EXISTS "+TABLE_CONTACT;
    db.execSQL(strDelete);

    onCreate(db);
    }
}
  • 注意,因为您已经在运行该应用程序,该数据库(尽管没有任何表)仍将存在,因此 onCreate 方法将不会运行。因此,在更改两个表的CREATE TABLE SQL之后,您需要执行以下操作之一:-

  • 删除/清除应用数据。

  • 卸载应用。
  • 增加数据库版本号(例如,将private static final int DATABASE_VERSION = 1;更改为private static final int DATABASE_VERSION = 2;

完成上述操作之一后,您可以重新运行该应用程序。

P.S。堆栈跟踪将遵循:-

2018-12-30 11:11:41.029 3278-3278/? E/SQLiteLog: (1) near "AUTOINCRENEMT": syntax error
2018-12-30 11:11:41.030 3278-3278/? D/AndroidRuntime: Shutting down VM
2018-12-30 11:11:41.032 3278-3278/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: so53958115.so53958115, PID: 3278
    java.lang.RuntimeException: Unable to start activity ComponentInfo{so53958115.so53958115/so53958115.so53958115.MainActivity}: android.database.sqlite.SQLiteException: near "AUTOINCRENEMT": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE User (_id INTEGER PRIMARY KEY AUTOINCRENEMT, name TEXT, age INTEGER);
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2914)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3049)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1809)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6680)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: android.database.sqlite.SQLiteException: near "AUTOINCRENEMT": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE User (_id INTEGER PRIMARY KEY AUTOINCRENEMT, name TEXT, age INTEGER);
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
        at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1769)
        at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1698)
        at so53958115.so53958115.HelperDB.onCreate(HelperDB.java:34)
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:393)
        at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:298)
        at so53958115.so53958115.MainActivity.onCreate(MainActivity.java:26)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2894)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3049) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1809) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6680) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)