Как исправить вставки данных в Android SQLite? - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь вставить данные в базу данных sqlite, но вывод не отображается.

activity_main.xml

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="12dp"
        android:text="Add a new Payment"
        android:textAlignment="center"
        android:textAppearance="@style/Base.TextAppearance.AppCompat.Large" />
    <EditText
        android:id="@+id/editTextName1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Invoice id" />

    <EditText
        android:id="@+id/editTextName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Customer Name" />

    <EditText
        android:id="@+id/editTextName2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Credit Card" />
    <EditText
        android:id="@+id/editTextName3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Renewal Date" />
    <EditText
        android:id="@+id/editTextName4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Expiry Date" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:paddingLeft="6dp"
        android:text="Select Packages" />
    <Spinner
        android:id="@+id/spinnerPackages"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/Packages" />
    <EditText
        android:id="@+id/editTextName5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Total Amount" />
    <Button
        android:id="@+id/buttonAddPayment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Add Payment" />
    <TextView
        android:id="@+id/textViewViewEmployees"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="View Payment"
        android:textAlignment="center"
        android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
        android:textStyle="bold" />

Класс менеджера баз данных

Обратите внимание, что: invoice_id INTEGER PRIMARY KEY <--- Это не автоинкремент и дата обновления TEXT, expiry_date TEXT, total_amount TEXT <--- Тип данных - TEXT </strong>

public class DatabaseManager extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Gym.db";
public static final String TABLE_NAME = "Payment";
public static final String KEY_NAME = "invoice_id";
public static final String KEY_NAME2 = "customer_name";
public static final String KEY_NAME3 = "credit_card";
public static final String KEY_NAME4 = "renewal_date";
public static final String KEY_NAME5 = "expiry_date";
public static final String KEY_NAME6 = "membership";
public static final String KEY_NAME7 = "total_amount";
public DatabaseManager( Context context) {
    super(context, DATABASE_NAME, null, 1);
}

@Override
public void onCreate(SQLiteDatabase db) {

    db.execSQL("create table " + TABLE_NAME +" (invoice_id INTEGER PRIMARY KEY ,customer_name TEXT ,credit_card TEXT ,renewal_date TEXT , expiry_date TEXT , membership TEXT, total_amount TEXT);");

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
    onCreate(db);
}
public boolean insertData(String invoice_id, String customer_name, String credit_card, String renewal_date, String expiry_date, String total_amount, String membership){
SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
  contentValues.put(KEY_NAME, invoice_id);
    contentValues.put(KEY_NAME2, customer_name);
    contentValues.put(KEY_NAME3, credit_card);
    contentValues.put(KEY_NAME4, renewal_date);
    contentValues.put(KEY_NAME5, expiry_date);
    contentValues.put(KEY_NAME6, membership);
    contentValues.put(KEY_NAME7, total_amount);
  long result =  db.insert(TABLE_NAME,null, contentValues); // error here
  // If data is inserted incorrectly it will return -1
    if (result == -1) {
      return false;
  }else {
      return true;
  }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
   DatabaseManager myDb;
   EditText editInvoiceid, editName, editCreditCard, editRenewDate, 
   editExpiryDate, edittotalamt;
    Spinner membership;
    TextView textViewViewPayments;
   Button btnAddData;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    myDb = new DatabaseManager (this);

    //Cast variables over here.
    editInvoiceid = (EditText) findViewById(R.id.editTextName1);
    editName = (EditText) findViewById(R.id.editTextName);
    editCreditCard = (EditText) findViewById(R.id.editTextName2);
    editRenewDate = (EditText) findViewById(R.id.editTextName3);
    editExpiryDate = (EditText) findViewById(R.id.editTextName4);
    edittotalamt = (EditText) findViewById(R.id.editTextName5);
    textViewViewPayments = (TextView) findViewById(R.id.textViewViewEmployees);
    membership = (Spinner) findViewById(R.id.spinnerPackages);
    btnAddData = (Button) findViewById(R.id.buttonAddPayment);
    AddData();
}
//Create a method for adding data
public void AddData() {
    btnAddData.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
         boolean isInserted = myDb.insertData(editInvoiceid.getText().toString(), editName.getText().toString(),editCreditCard.getText().toString(),editRenewDate.getText().toString(), editExpiryDate.getText().toString(),edittotalamt.getText().toString(), membership.toString());
        if (isInserted == true){
            Toast.makeText(MainActivity.this, "Data Inserted",Toast.LENGTH_LONG).show();
        }else {
            Toast.makeText(MainActivity.this, "Data Not Inserted",Toast.LENGTH_LONG).show();
        }

        }
    });
}

}

Как это исправить?

1 Ответ

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

Я считаю, что у вас есть одна из двух проблем.

Потенциальная проблема 1.

Возможно, вы изменили структуру базы данных и просто перезапустили приложение.В этом случае новые столбцы (как пример) не будут существовать, и это может вызвать сбой (исключение SQlite).

Если вы выполните одно из следующих действий до перезапуска приложения, такая проблема будет исправлена: -

  1. Удалите (очистите) данные приложения.
  2. УдалитеПриложение.
  3. Увеличение версии базы данных ( например, изменение super(context, DATABASE_NAME, null, 1); на super(context, DATABASE_NAME, null, 2);)

Потенциальная проблема 2.

Срок оплатыдля столбца invoice_id , определяемого как invoice_id INTEGER PRIMARY KEY, значение должно быть целочисленным, поскольку INTEGER PRIMARY KEY делает столбец псевдонимом специального столбца rowid , который должен быть значением INTEGER ROWID и INTEGER PRIMARY KEY ( AUTOINCREMENT - это просто расширение, которое требует, чтобы следующее автоматически назначаемое значение было больше, чем любое значение, которое существует или существовало ).

invoice_id также должно быть уникальным значением.

Сказав это, ваш код работает по крайней мере в моде.Для проверки вашего кода использовалось следующее: -

activity_main.xml внесено незначительное изменение в Spinner, удалив android:entries="@array/Packages".- Это было удалено, чтобы упростить тестирование, а также потому, что membership.toString() получит не значение выбранного элемента, а строковое представление объекта (см. Результат ниже) DatabaseManager.java согласно вопросу (т.е. нетизменения). MainActivity.java согласно: -

public class MainActivity extends AppCompatActivity {

    DBHelper mDBHlpr;

    DatabaseManager myDb;
    EditText editInvoiceid, editName, editCreditCard, editRenewDate, editExpiryDate, edittotalamt;
    Spinner membership;
    TextView textViewViewPayments;
    Button btnAddData;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myDb = new DatabaseManager (this);

        //Cast variables over here.
        editInvoiceid = (EditText) findViewById(R.id.editTextName1);
        editName = (EditText) findViewById(R.id.editTextName);
        editCreditCard = (EditText) findViewById(R.id.editTextName2);
        editRenewDate = (EditText) findViewById(R.id.editTextName3);
        editExpiryDate = (EditText) findViewById(R.id.editTextName4);
        edittotalamt = (EditText) findViewById(R.id.editTextName5);
        textViewViewPayments = (TextView) findViewById(R.id.textViewViewEmployees);
        membership = (Spinner) findViewById(R.id.spinnerPackages);
        btnAddData = (Button) findViewById(R.id.buttonAddPayment);
        AddData();
    }
    //Create a method for adding data
    public void AddData() {
        btnAddData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean isInserted = myDb.insertData(editInvoiceid.getText().toString(), editName.getText().toString(),editCreditCard.getText().toString(),editRenewDate.getText().toString(), editExpiryDate.getText().toString(),edittotalamt.getText().toString(), membership.toString());
                if (isInserted == true){
                    Toast.makeText(MainActivity.this, "Data Inserted",Toast.LENGTH_LONG).show();
                }else {
                    Toast.makeText(MainActivity.this, "Data Not Inserted",Toast.LENGTH_LONG).show();
                }
                logCurrentData(); //<<<<<<<<<< ADDED
            }
        });
    }

    /**
     * ADDED METHOD
     */
    private void logCurrentData() {
        DatabaseUtils.dumpCursor(
                myDb.getWritableDatabase().query(DatabaseManager.TABLE_NAME,null,null,null,null,null,null)
        );
    }
}
  • т.е. добавлен метод logCurrentData , и он вызывается в onClick method.

Результаты

Тест 1 Ввод: -

enter image description here

Результаты в (Тосты Вставленные данные ): -

2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@6a5e922
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out: 0 {
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out:    invoice_id=1
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out:    customer_name=Fred
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out:    credit_card=1234567890
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out:    renewal_date=10/19
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out:    expiry_date=10/19
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out:    membership=android.support.v7.widget.AppCompatSpinner{ec45337 V.ED..CL. ........ 0,320-1080,344 #7f07007c app:id/spinnerPackages}
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out:    total_amount=50.00
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out: }
2018-12-31 21:45:40.282 2266-2266/so53976714.so53976714 I/System.out: <<<<<
  • Примечание: членство в программе связано с memebership.toString (), как описано выше.

Тест 2 Измените Fred на Bert и попробуйте добавить: -

приводит к Данные не вставлены журнал включает следующее (а также точно такие же данные, как в предыдущем тесте): -

2018-12-31 21:50:14.115 2266-2266/so53976714.so53976714 E/SQLiteDatabase: Error inserting credit_card=1234567890 renewal_date=10/19 total_amount=50.00 expiry_date=10/19 invoice_id=1 customer_name=Bert membership=android.support.v7.widget.AppCompatSpinner{ec45337 V.ED..CL. ........ 0,320-1080,344 #7f07007c app:id/spinnerPackages}
    android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: Payment.invoice_id (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1564)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1433)
        at so53976714.so53976714.DatabaseManager.insertData(DatabaseManager.java:47)
        at so53976714.so53976714.MainActivity$1.onClick(MainActivity.java:45)
        at android.view.View.performClick(View.java:6597)
        at android.view.View.performClickInternal(View.java:6574)
        at android.view.View.access$3100(View.java:778)
        at android.view.View$PerformClick.run(View.java:25885)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        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)
  • Примечание исключение было перехвачено и не вызывает сбоя.
  • Как видно из значения invoice_id (в данном случае 1)) нельзя дублировать.

Тест 3 Попробуйте изменить invoice_id с 1 на A (все еще с Берт вместо Фреда): -

Результаты в Данные не вставлены .Однако журнал включает в себя: -

2018-12-31 21:54:51.818 2266-2266/so53976714.so53976714 E/SQLiteLog: (20) statement aborts at 5: [INSERT INTO Payment(credit_card,renewal_date,total_amount,expiry_date,invoice_id,customer_name,membership) VALUES (?,?,?,?,?,?,?)] datatype mismatch
2018-12-31 21:54:51.820 2266-2266/so53976714.so53976714 E/SQLiteDatabase: Error inserting credit_card=1234567890 renewal_date=10/19 total_amount=50.00 expiry_date=10/19 invoice_id=A customer_name=Bert membership=android.support.v7.widget.AppCompatSpinner{ec45337 V.ED..CL. ........ 0,320-1080,344 #7f07007c app:id/spinnerPackages}
    android.database.sqlite.SQLiteDatatypeMismatchException: datatype mismatch (code 20 SQLITE_MISMATCH)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1564)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1433)
        at so53976714.so53976714.DatabaseManager.insertData(DatabaseManager.java:47)
        at so53976714.so53976714.MainActivity$1.onClick(MainActivity.java:45)
        at android.view.View.performClick(View.java:6597)
        at android.view.View.performClickInternal(View.java:6574)
        at android.view.View.access$3100(View.java:778)
        at android.view.View$PerformClick.run(View.java:25885)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        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)
  • снова исключение перехватывается.

Test4 изменяет invoice_id на 2: -

Result Данные вставлены и журнал включает в себя: -

2018-12-31 22:10:32.902 2266-2266/so53976714.so53976714 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@4d18939
2018-12-31 22:10:32.905 2266-2266/so53976714.so53976714 I/System.out: 0 {
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    invoice_id=1
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    customer_name=Fred
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    credit_card=1234567890
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    renewal_date=10/19
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    expiry_date=10/19
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    membership=android.support.v7.widget.AppCompatSpinner{ec45337 V.ED..CL. ........ 0,320-1080,344 #7f07007c app:id/spinnerPackages}
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    total_amount=50.00
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out: }
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out: 1 {
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    invoice_id=2
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    customer_name=Bert
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    credit_card=1234567890
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    renewal_date=10/19
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    expiry_date=10/19
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    membership=android.support.v7.widget.AppCompatSpinner{ec45337 V.ED..CL. ........ 0,320-1080,344 #7f07007c app:id/spinnerPackages}
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out:    total_amount=50.00
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out: }
2018-12-31 22:10:32.906 2266-2266/so53976714.so53976714 I/System.out: <<<<<
...