为什么db.insertWithOnConflict在这里返回-1?

时间:2017-12-12 10:52:42

标签: java android database sqlite android-sqlite

在此活动中,我们可以输入学校测试的信息,并将其添加到其他测试中。

Test.java:

package com.example.amirmasoudfallahi.testcorrector;

import android.content.ContentValues;
import android.database.Cursor;

/**
 * Created by AmirMasoud Fallahi on 11/18/2017.
 */

public class Test {

  public static final String KEY_ID = "testID";
  public static final String KEY_NAME = "testName";
  public static final String KEY_SCHOOL_NAME = "schName";
  public static final String KEY_QUESTION_NUM = "quesNum";
  public static final String KEY_PARTICIPANT_NUM = "participantNum";
  public static final String KEY_QUALITY_MARK = "qualityMark";
  public static final String KEY_LESSON_NUM = "lessonNum";

  private int testID;
  private String testName;
  private String schName;
  private int quesNum;
  private int participantNum;
  private float qualityMark = 0;
  private int lessonNum;

  public int getLessonNum() {
    return lessonNum;
  }

  public void setLessonNum(int lessonNum) {
    this.lessonNum = lessonNum;
  }

  public String getName() {
    return testName;
  }

  public void setName(String name) {
    this.testName = name;
  }

  public String getSchName() {
    return schName;
  }

  public void setSchName(String schName) {
    this.schName = schName;
  }

  public int getQuesNum() {
    return quesNum;
  }

  public void setQuesNum(int quesNum) {
    this.quesNum = quesNum;
  }

  public int getParticipantNum() {
    return participantNum;
  }

  public void setParticipantNum(int participantNum) {
    this.participantNum = participantNum;
  }

  public float getQualityMark() {
    return qualityMark;
  }

  public void setQualityMark(float qualityMark) {
    this.qualityMark = qualityMark;
  }

  public int getId() {
    return testID;
  }

  public void setId(int id) {
    this.testID = id;
  }

  @Override
  public String toString() {
    return testName;
  }

  public ContentValues getContentValuesForDb(){
    ContentValues values = new ContentValues();
    values.put(Test.KEY_ID, testID);
    values.put(Test.KEY_NAME, testName);
    values.put(Test.KEY_SCHOOL_NAME, schName);
    values.put(Test.KEY_QUESTION_NUM, quesNum);
    values.put(Test.KEY_LESSON_NUM, lessonNum);
    values.put(Test.KEY_QUALITY_MARK, qualityMark);
    values.put(Test.KEY_PARTICIPANT_NUM, participantNum);
    return values;
  }

  public static Test cursorToTest(Cursor cursor){
    Test test = new Test();
    test.setId(cursor.getInt(cursor.getColumnIndex(KEY_ID)));
    test.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
    test.setQuesNum(cursor.getInt(cursor.getColumnIndex(KEY_QUESTION_NUM)));
    test.setParticipantNum(cursor.getInt(cursor.getColumnIndex(KEY_PARTICIPANT_NUM)));
    test.setSchName(cursor.getString(cursor.getColumnIndex(KEY_SCHOOL_NAME)));
    test.setQualityMark(cursor.getInt(cursor.getColumnIndex(KEY_QUALITY_MARK)));
    test.setLessonNum(cursor.getInt(cursor.getColumnIndex(KEY_LESSON_NUM)));
    return test;
  }

}

TestDbHelper.java:

package com.example.amirmasoudfallahi.testcorrector;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by AmirMasoud Fallahi on 11/20/2017.
 */

public class TestDBHelper extends SQLiteOpenHelper {

  private static final String DB_NAME = "test-db";
  private static final int DB_VERSION = 1;

  public static final String TABLE_TESTS = "tb_tests";
  private static final String CMD =
    "CREATE TABLE IF NOT EXISTS '" + TABLE_TESTS + "' ('" +
      Test.KEY_ID + "' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, '" +
      Test.KEY_NAME + "' TEXT, '" +
      Test.KEY_SCHOOL_NAME + "' TEXT, '" +
      Test.KEY_QUESTION_NUM + "' INTEGER, '" +
      Test.KEY_LESSON_NUM + "' INTEGER, '" +
      Test.KEY_QUALITY_MARK + "' REAL, '" +
      Test.KEY_PARTICIPANT_NUM + "' INTEGER " +
      ")";

  private static final String[] allColumns = {Test.KEY_ID, Test.KEY_NAME, Test.KEY_SCHOOL_NAME,
    Test.KEY_QUESTION_NUM, Test.KEY_PARTICIPANT_NUM, Test.KEY_QUALITY_MARK, Test.KEY_LESSON_NUM};


  public TestDBHelper(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
  }

  @Override
  public void onCreate(SQLiteDatabase db) {
    db.execSQL(CMD);
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_TESTS);
    onCreate(db);
  }

  public void insetItem(Test test) {
//    if(getTests(Test.KEY_ID + " = " + test.getId()).isEmpty()) {
    SQLiteDatabase db = getWritableDatabase();
    long insertId = db.insertWithOnConflict(TABLE_TESTS, null, test.getContentValuesForDb(), SQLiteDatabase.CONFLICT_REPLACE);
    if(insertId == -1) {
      Log.i("TestDbHelper", "data insertion failed. (item : " + test.toString() + ")");
    } else {
      Log.i("TestDbHelper", "data inserted with id : " + insertId);
    }
    if(db.isOpen()) db.close();
//    }
  }

  public List<Test> getTests(String selection){
    SQLiteDatabase db = getReadableDatabase();
    List<Test> testList = new ArrayList<>();

    Cursor cursor = db.query(TABLE_TESTS, allColumns, selection, null, null, null, null);
    if(cursor.moveToFirst()){
      do{
        Test test = Test.cursorToTest(cursor);
        testList.add(test);
      } while (cursor.moveToNext());
    }
    cursor.close();
    if(db.isOpen()) db.close();
    return testList;
  }

}

DefineTestActivity.java:

package com.example.amirmasoudfallahi.testcorrector;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class DefineTestActivity extends AppCompatActivity {

  TestDBHelper dbHelper;
  EditText inputTestName, inputSchName, inputPrtNum, inputQuesNum, inputLessNum;
  Button subTest;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_define_test);

    dbHelper = new TestDBHelper(this);

    inputTestName = (EditText) findViewById(R.id.txt_testNameIn);
    inputSchName = (EditText) findViewById(R.id.txt_schNameIn);
    inputPrtNum = (EditText) findViewById(R.id.txt_prtcpntNumIn);
    inputQuesNum = (EditText) findViewById(R.id.txt_testQuesNumIn);
    inputLessNum = (EditText) findViewById(R.id.txt_lessNum);
    subTest = (Button) findViewById(R.id.btn_createTestSubmit);

    subTest.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        Test test = new Test();
        test.setName(inputTestName.getText().toString().trim());
        test.setSchName(inputSchName.getText().toString().trim());
        test.setQuesNum(Integer.parseInt(inputQuesNum.getText().toString().trim()));
        test.setParticipantNum(Integer.parseInt(inputPrtNum.getText().toString().trim()));
        test.setLessonNum(Integer.parseInt(inputLessNum.getText().toString().trim()));

        dbHelper.insetItem(test);

        Intent intent = new Intent(DefineTestActivity.this, AnswerKeysActivity.class);
        intent.putExtra("lessonNum", test.getLessonNum());
        startActivity(intent);
      }
    });
  }
}

活动预览:

[activity preview]

在这种情况下,我输入要添加到测试列表中的新测试的信息。 当我按下按钮时,它应该添加一个新的测试来测试数据库中的表。 如你所见,在这一行中它应该添加它:

dbHelper.insetItem(test); 

是插入函数,在这一行:

long insertId = db.insertWithOnConflict(TABLE_TESTS, null, test.getContentValuesForDb(), SQLiteDatabase.CONFLICT_REPLACE);

它应该添加它并返回非-1。 但它返回-1,表明我们的插入失败了。

没有错误。而且我实际上不知道为什么它得到-1并且没有在DB中插入该项目。

任何人都可以解决这个问题???

1 个答案:

答案 0 :(得分:0)

确保表中有一些适当的约束,例如PRIMARY KEY或UNIQUE。 插入时,通过ContentValues向此约束列添加值。如果插入新行会违反某些约束,则首先删除冲突的行,然后插入新行。 在您的情况下,COLUMN_ID看起来像是PRIMARY KEY约束的良好候选者。您的代码中没有必要使用值为COLUMN_ID的第二个arg nullColumnHack,您可以将其作为null传递。