SQLite: db.insert не работает внутри оператора ifAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 SQLite: db.insert не работает внутри оператора if

Сообщение Anonymous »

Я пытаюсь использовать базу данных SQLite для хранения информации для представления переработчика. Хотелось бы, чтобы в базе данных были только уникальные записи по их описанию. Я пытался установить уникальное поле описания при создании базы данных, но, похоже, это не помогло. Вместо этого я решил создать функцию, которая проверяет, существует ли описание в базе данных, а затем вставляет новую запись с этой информацией. Эта функция работает нормально после запуска инструмента отладки, чтобы увидеть, где я ошибся. Я думаю, что ошибка заключается в функции db.insert, которая, похоже, не выполняется внутри оператора if. Любая помощь приветствуется.

P.S. Я полный новичок в SQLite и не очень знаком с его жаргоном.

Вот часть кода класса, который помогает работать с базой данных.

Код: Выделить всё

public class DataBaseHandler extends SQLiteOpenHelper {

private final Context context;

public DataBaseHandler(@Nullable Context context) {
super(context, Constants.DB_NAME, null, Constants.DB_VERSION);
this.context = context;
}

@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_FOOD_TABLE = "CREATE TABLE " + Constants.TABLE_NAME + "("
+ Constants.KEY_ID + " INTEGER PRIMARY KEY,"
+ Constants.KEY_FOOD_ITEM + " INTEGER,"
+ Constants.KEY_PRICE + " TEXT,"
+ Constants.KEY_QTY_NUMBER + " INTEGER,"
+ Constants.KEY_DESCRIPTION + " TEXT,"
+ Constants.KEY_DATE_NAME + " LONG);";

db.execSQL(CREATE_FOOD_TABLE);
}
Вот код функции hasObject:

Код: Выделить всё

    public boolean hasObject(String foodCode) {
SQLiteDatabase db = getWritableDatabase();
String selectString = "SELECT * FROM " + Constants.TABLE_NAME + " WHERE " + Constants.KEY_DESCRIPTION + " =?";

// Add the String you are searching by here.
// Put it in an array to avoid an unrecognized token error
Cursor cursor = db.rawQuery(selectString, new String[] {foodCode});

boolean hasObject = false;
if(cursor.moveToFirst()){
hasObject = true;
}

cursor.close();
db.close();
return hasObject;
}
Константы определены в отдельном классе как статический финал.

Вот мой код, в котором возникла проблема существует.

Код: Выделить всё

public void addItem(Item item) {
SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();
values.put(Constants.KEY_FOOD_ITEM, item.getItemName());
values.put(Constants.KEY_PRICE, item.getPrice_double());
values.put(Constants.KEY_QTY_NUMBER, item.getItemQuantity());
values.put(Constants.KEY_DESCRIPTION, item.getDescription());
values.put(Constants.KEY_DATE_NAME,
java.lang.System.currentTimeMillis());//timestamp of the system

//        db.insert(Constants.TABLE_NAME, null, values);
//        Log.d("DBHandler", "added Item: ");
//Check if the record already exists in the database
if(!hasObject(item.getDescription())){
//Insert the row
db.insert(Constants.TABLE_NAME, null, values);              // This is not running as planned
Log.d("DBHandler", "added Item: ");
}
else {
//Don't insert the row
Log.d("DBHandler", "Item exists");

}
}
Как вы заметили, я попробовал запустить функцию db.insert как есть, не проверяя, существует ли уже запись в базе данных, и она работает нормально.
Но если я продолжу добавлять записи независимо от того, находятся ли они в базе данных, будет слишком много дубликатов, и это испортит представление переработчика.

Функция additem сюда звонят:

Код: Выделить всё

        databaseHandler= new DataBaseHandler(this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

itemList= new ArrayList();
//tempitemlist = new ArrayList();

//Get items from Firebase
mfoodRef.addValueEventListener(new ValueEventListener() {
//Will run everytime there is an update to the condition value in the database
//So this will run when the .setValue function runs in the button onClickListener classes
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
//tempitemlist.clear();
Iterable databaseMenu = dataSnapshot.getChildren();
for (DataSnapshot data:databaseMenu){
Menu tempMenu = data.getValue(Menu.class);
Item tempItem = new Item(tempMenu.getFoodName(),tempMenu.getFoodCode(),tempMenu.getFoodPrice());
//itemList.add(tempItem);
databaseHandler.addItem(tempItem);
}
}

// In case we run into any errors
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {

}
});
И да, я использую информацию из своей базы данных реального времени Firebase для обновления содержимого обработчика базы данных в методе onDataChange. Вот почему мне нужно проверять наличие дубликатов при вставке новой записи.

РЕДАКТИРОВАТЬ:

Это это то, что я нашел в журнале отладки:

Код: Выделить всё

    Process: com.example.vendorwrecycler, PID: 12882
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/user/0/com.example.vendorwrecycler/databases/foodList
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:57)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1567)
at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1494)
at com.example.vendorwrecycler.data.DataBaseHandler.addItem(DataBaseHandler.java:68)
at com.example.vendorwrecycler.ListActivity.saveItem(ListActivity.java:184)
at com.example.vendorwrecycler.ListActivity.access$500(ListActivity.java:34)
at com.example.vendorwrecycler.ListActivity$4.onClick(ListActivity.java:159)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Может быть, это как-то связано с IllegalStateException?

Подробнее здесь: https://stackoverflow.com/questions/591 ... -statement
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»