#android-sqlite
Вопрос:
Я пытаюсь создать базу данных с помощью SQLite. но я не понимаю, какую именно ошибку я делаю в своем коде.. таблица не создается и onUpgrade не вызывается…Я перепробовал все … теперь кто-нибудь может мне помочь с этим, пожалуйста?
Ява
package com.example.mysqlitedemo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
public class NewDatabsehelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME="Profile.dB";
private static final String TABLE_NAME="Profile";
private static final String NAME="Nme";
private static final String AGE="Age";
private static final String ID="id";
private static final String PHONE="Phone";
private static final String CREATE_TABLE=
"CREATE TABLE " TABLE_NAME " ( " NAME " VARCHAR(255),"
"" AGE " INTEGERE,"
"" ID " INTEGER PRIMARY KEY AUTOINCREMENT," PHONE " INTEGER);";
private final Context context;
public NewDatabsehelper( Context context) {
super(context, DATABASE_NAME, null, 6);
this.context=context;
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
Toast.makeText(context,"Oncreate is called",Toast.LENGTH_SHORT).show();
db.execSQL(CREATE_TABLE);
}catch ( Exception e){
Toast.makeText(context,"Exception " e,Toast.LENGTH_SHORT).show();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Toast.makeText(context,"Onupgrade is called",Toast.LENGTH_SHORT).show();
db.execSQL("DROP TABLE IF EXISTS " TABLE_NAME);
onCreate(db);
}catch (Exception e){
Toast.makeText(context,"Exception " e,Toast.LENGTH_SHORT).show();
}
}
}
это моя основная деятельность
package com.example.mysqlitedemo;
import androidx.appcompat.app.AppCompatActivity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
NewDatabsehelper newDatabsehelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
newDatabsehelper=new NewDatabsehelper(this);
SQLiteDatabase sqLiteDatabase=newDatabsehelper.getWritableDatabase();
}
}
И после выполнения этого я не нашел таблицы, созданной в базе данных SQLite.
Комментарии:
1. Итак, вы пытались обновить версию своей базы данных?
2. @MahmoudMohamedRamadan да, брат, я продолжал меняться со 2 на 6
3. @MahmoudMohamedRamadan, но я не могу создать открытую базу данных mehtod public void () { }, как это сделали вы.. и не могу получить к ней доступ из Mainactivity . он помечен красным, говоря, что требуется выражение
4. КАК ?! Я уже пробовал это решение раньше и оно работает правильно для меня
Ответ №1:
И после выполнения этого я не нашел таблицы, созданной в базе данных SQLite.
Я считаю, что ваш код работает, но проблема в том, как вы пытаетесь определить, существует ли таблица.
Возможно, рассмотрите следующую адаптацию вашего кода.
Адаптация вносит 3 изменения, чтобы вы могли видеть, что происходит. IT
- записывает сообщения в журнал в дополнение к тостам.
- тосты недолговечны и их легко пропустить, журнал существует гораздо дольше
- позволяет передавать версию базы данных помощнику.
- в основном действии он извлекает таблицы из схемы баз данных (он же sqlite_master) и сбрасывает извлеченные данные в журнал.
- т. е. запрашивается sqlite_master, и возвращенный курсор сбрасывается (записывается в журнал).
- после получения первого экземпляра NewDatabasehelper и сброса схемы он закрывает эту базу данных, а затем получает второй экземпляр с более высокой версией и снова сбрасывает схему.
Таким образом, это показывает, что таблица профилей существует.
Таким образом, измененный (но функционально тот же) NewDatabsehelper является :-
public class NewDatabsehelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME="Profile.dB";
private static final String TABLE_NAME="Profile";
private static final String NAME="Nme";
private static final String AGE="Age";
private static final String ID="id";
private static final String PHONE="Phone";
private static final String CREATE_TABLE=
"CREATE TABLE " TABLE_NAME " ( " NAME " VARCHAR(255),"
"" AGE " INTEGERE,"
"" ID " INTEGER PRIMARY KEY AUTOINCREMENT," PHONE " INTEGER);";
private final Context context;
private final String TAG = "DBINFO"; //<<<<<<<<<< ADDED (just to tag logged messages)
public NewDatabsehelper( Context context, int dbversion) { //<<<<<<<<<< CHANGED to require passed version rather than hard coded
super(context, DATABASE_NAME, null, dbversion); //<<<<<<<<<< CHANGED to pass the pased version to the super call
this.context=context;
}
@Override
public void onCreate(SQLiteDatabase db) {
Toast.makeText(context,"Oncreate is called",Toast.LENGTH_SHORT).show(); //<<<<<<<<<< moved to outside the try/catch
Log.d(TAG,"onCreate Invoked DBVersion is " db.getVersion()); //<<<<<<<<<< ADDED
try {
db.execSQL(CREATE_TABLE);
}catch ( Exception e){
Log.d(TAG,"onCreate Exception " e.getMessage()); //<<<<<<<<<< ADDED
Toast.makeText(context,"Exception " e,Toast.LENGTH_SHORT).show();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Toast.makeText(context,"onUpgrade is called",Toast.LENGTH_SHORT).show(); //<<<<<<<<<< moved to outside the try/catch
Log.d(TAG,"onUpgrade Invoked for version(fromDB) " db.getVersion() " oldVersion is " oldVersion " newVersion is " newVersion); //<<<<<<<<<< ADDED
try {
db.execSQL("DROP TABLE IF EXISTS " TABLE_NAME);
onCreate(db);
}catch (Exception e){
Toast.makeText(context,"Exception " e,Toast.LENGTH_SHORT).show();
Log.d(TAG,"onUpgrade Exception " e.getMessage()); //<<<<<<<<<< ADDED
}
}
}
Основная деятельность :-
public class MainActivity extends AppCompatActivity {
NewDatabsehelper newDatabsehelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
newDatabsehelper=new NewDatabsehelper(this,10); // Changed to pass version
SQLiteDatabase sqLiteDatabase=newDatabsehelper.getWritableDatabase();
/* Added to write database schema to the log and then close the database */
Cursor csr = sqLiteDatabase.query("sqlite_master",null,null,null,null,null,null);
DatabaseUtils.dumpCursor(csr);
csr.close();
sqLiteDatabase.close();
/* ADDED to repeat the above BUT with higher version number, thus forcing onUpgrade */
newDatabsehelper = new NewDatabsehelper(this,11);
sqLiteDatabase=newDatabsehelper.getWritableDatabase();
csr = sqLiteDatabase.query("sqlite_master",null,null,null,null,null,null);
DatabaseUtils.dumpCursor(csr);
csr.close();
}
}
Когда приложение запущено и является новым, журнал включает :-
2021-09-23 06:28:23.871 D/DBINFO: onCreate Invoked DBVersion is 0
2021-09-23 06:28:23.872 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@b0309ff
2021-09-23 06:28:23.873 I/System.out: 0 {
2021-09-23 06:28:23.873 I/System.out: type=table
2021-09-23 06:28:23.873 I/System.out: name=android_metadata
2021-09-23 06:28:23.873 I/System.out: tbl_name=android_metadata
2021-09-23 06:28:23.873 I/System.out: rootpage=3
2021-09-23 06:28:23.873 I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
2021-09-23 06:28:23.873 I/System.out: }
2021-09-23 06:28:23.873 I/System.out: 1 {
2021-09-23 06:28:23.873 I/System.out: type=table
2021-09-23 06:28:23.873 I/System.out: name=Profile
2021-09-23 06:28:23.874 I/System.out: tbl_name=Profile
2021-09-23 06:28:23.874 I/System.out: rootpage=4
2021-09-23 06:28:23.874 I/System.out: sql=CREATE TABLE Profile ( Nme VARCHAR(255),Age INTEGERE,id INTEGER PRIMARY KEY AUTOINCREMENT,Phone INTEGER)
2021-09-23 06:28:23.874 I/System.out: }
2021-09-23 06:28:23.874 I/System.out: 2 {
2021-09-23 06:28:23.874 I/System.out: type=table
2021-09-23 06:28:23.874 I/System.out: name=sqlite_sequence
2021-09-23 06:28:23.874 I/System.out: tbl_name=sqlite_sequence
2021-09-23 06:28:23.874 I/System.out: rootpage=5
2021-09-23 06:28:23.874 I/System.out: sql=CREATE TABLE sqlite_sequence(name,seq)
2021-09-23 06:28:23.874 I/System.out: }
2021-09-23 06:28:23.874 I/System.out: <<<<<
2021-09-23 06:28:23.889 D/DBINFO: onUpgrade Invoked for version(fromDB) 10 oldVersion is 10 newVersion is 11
2021-09-23 06:28:23.893 D/DBINFO: onCreate Invoked DBVersion is 10
2021-09-23 06:28:23.898 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@d047d2a
2021-09-23 06:28:23.898 I/System.out: 0 {
2021-09-23 06:28:23.898 I/System.out: type=table
2021-09-23 06:28:23.898 I/System.out: name=android_metadata
2021-09-23 06:28:23.898 I/System.out: tbl_name=android_metadata
2021-09-23 06:28:23.898 I/System.out: rootpage=3
2021-09-23 06:28:23.898 I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
2021-09-23 06:28:23.898 I/System.out: }
2021-09-23 06:28:23.898 I/System.out: 1 {
2021-09-23 06:28:23.898 I/System.out: type=table
2021-09-23 06:28:23.898 I/System.out: name=sqlite_sequence
2021-09-23 06:28:23.898 I/System.out: tbl_name=sqlite_sequence
2021-09-23 06:28:23.899 I/System.out: rootpage=4
2021-09-23 06:28:23.899 I/System.out: sql=CREATE TABLE sqlite_sequence(name,seq)
2021-09-23 06:28:23.899 I/System.out: }
2021-09-23 06:28:23.899 I/System.out: 2 {
2021-09-23 06:28:23.899 I/System.out: type=table
2021-09-23 06:28:23.899 I/System.out: name=Profile
2021-09-23 06:28:23.899 I/System.out: tbl_name=Profile
2021-09-23 06:28:23.899 I/System.out: rootpage=5
2021-09-23 06:28:23.899 I/System.out: sql=CREATE TABLE Profile ( Nme VARCHAR(255),Age INTEGERE,id INTEGER PRIMARY KEY AUTOINCREMENT,Phone INTEGER)
2021-09-23 06:28:23.899 I/System.out: }
2021-09-23 06:28:23.899 I/System.out: <<<<<
Поскольку базы данных не существует и нет файла, из которого можно было бы получить номер версии, при вызове onCreate номер версии равен 0 (как и следовало ожидать при первой установке приложения). После того, как onCreate был вызван/запущен, таблица профилей существует в соответствии со схемой.
- android_metadata создается android API и хранит языковой стандарт
- sqlite_sequence создается SQLite, поскольку вы закодировали АВТОИНКРЕМЕНТ, он используется для хранения самого высокого используемого идентификатора строки (ваш столбец идентификатора является псевдонимом столбца rowid).
Второе извлечение экземпляра (4 пустые строки, добавленные для отличия второго от первого) показывает, что
- версия базы данных составляет 10
- Был вызван onUpgrade и что новая версия будет 11.
- onCreate был вызван из onUpgrade
- и снова, что таблица существует после того, как ее отбросили.
Другой способ проверить, существуют ли база данных и таблицы в ней, — это использовать инспектор приложений Android Stuido, например :-
Ответ №2:
Почти все хорошо, НО позвольте мне угадать проблему, вы можете попробовать следующий код
package com.example.mysqlitedemo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
public class NewDatabsehelper extends SQLiteOpenHelper {
private SQLiteDatabase db;
private static final String DATABASE_NAME = "Profile.dB";
private static final int DATABASE_VERSION = 7;
private static final String TABLE_NAME = "Profile";
private static final String NAME = "Name";
private static final String AGE = "Age";
private static final String ID = "id";
private static final String PHONE = "Phone";
private static final String CREATE_TABLE =
"CREATE TABLE IF NOT EXISTS " TABLE_NAME "("
NAME " VARCHAR(255),"
AGE " INTEGERE,"
PHONE " INTEGER,"
ID " INTEGER PRIMARY KEY AUTOINCREMENT);";
private final Context context;
public NewDatabsehelper( Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context=context;
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
Toast.makeText(context, "onCreate is called", Toast.LENGTH_SHORT).show();
db.execSQL(CREATE_TABLE);
} catch ( Exception e){
Toast.makeText(context, "Exception " e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Toast.makeText(context, "onUpgrade is called", Toast.LENGTH_SHORT).show();
db.execSQL("DROP TABLE IF EXISTS " TABLE_NAME);
onCreate(db);
} catch (Exception e){
Toast.makeText(context, "Exception " e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
public void openDatabase() {
db = this.getWritableDatabase();
}
}
и в вашем MainActivity.java
package com.example.mysqlitedemo;
import androidx.appcompat.app.AppCompatActivity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
NewDatabsehelper newDatabsehelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
newDatabsehelper = new NewDatabsehelper(this);
newDatabsehelper.openDatabase();
}
}