Сбой базы данных SQLite при создании - PullRequest
0 голосов
/ 30 декабря 2018

Я настраиваю приложение, которое получает информацию от пользователя в MainActivity, передает ее так, что SecondActivity отображает информацию в списке просмотра.

Я попытался найти основной фактор, вызывающий проблему, и обнаружил, что это был Database Builder, не смог найти причину.

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);
    }
}

Когда я создаю HelperDB на моемMainActivity происходит сбой в части, вставленной в раздел OnCreate: -

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

Приложение продолжает сбой, когда я удаляю сборку HelperDB, приложение работает нормально.Пожалуйста, помогите мне найти решение для этого.

1 Ответ

0 голосов
/ 30 декабря 2018

Вы используете неправильное ключевое слово. AUTOINCRENEMT должно быть AUTOINCREMENT (оба варианта).

Однако рекомендуется не кодировать AUTOINCREMENT, это неэффективно и практически определенно не требуется.Согласно: - Автоинкремент SQLite

, который включает в себя: -

Сводка

Ключевое слово AUTOINCREMENT накладывает дополнительный ЦП, память,места на диске и дискового ввода-вывода и их следует избегать, если в этом нет особой необходимости.Обычно это не требуется.

В SQLite столбец с типом INTEGER PRIMARY KEY является псевдонимом для ROWID (кроме таблиц WITHOUT ROWID), который всегда представляет собой 64-разрядное целое число со знаком.

В INSERT, если столбцу ROWID или INTEGER PRIMARY KEY явно не дано значение, он будет автоматически заполнен неиспользованным целым числом, обычно на единицу больше, чем самый большой ROWID, используемый в настоящее время.Это верно независимо от того, используется ли ключевое слово AUTOINCREMENT.

Если ключевое слово AUTOINCREMENT появляется после INTEGER PRIMARY KEY, это изменяет алгоритм автоматического назначения 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.
    • note `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;

После выполнения одного из указанных выше действий вы можете перезапустить приложение.

PS Трассировка стека была бы такой: -

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) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...