4

我知道有這麼多的線程關於這個問題,但沒有我自己的問題。 我有一個微調器連接在數據庫中,顯示特定表的外鍵。它出現錯誤插入。錯誤插入android.database.sqlite.sqliteconstraintexception錯誤代碼19約束失敗

02-18 11:44:34.500: E/SQLiteDatabase(20811): Error inserting [email protected] kWh=801.0 _id=65324 Date=2013 -2-18 Previous=98 Current=899

02-18 11:44:34.500: E/SQLiteDatabase(20811): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed

public class ElectricMeterReader extends Activity { 

    private long rowID; 

    private EditText meterNoEt; 
    private EditText currentEt; 
    private EditText previousEt; 
    private EditText kWhEt; 
    private TextView dateTv; 
    private Spinner spinner; 
    private int mSpinnerSpeciesId; 

    private ElectricMeterReader mContext; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.electric_meter_reader); 

    Bundle extras = getIntent().getExtras(); 

    // rowID = extras.getLong(ConsumerList.ROW_ID); 

    dateTv = (TextView) findViewById(R.id.dateEmr); 
    meterNoEt = (EditText) findViewById(R.id.meterNumberEmr); 
    currentEt = (EditText) findViewById(R.id.currentReadingEmr); 
    previousEt = (EditText) findViewById(R.id.passReadingEmr); 
    kWhEt = (EditText) findViewById(R.id.kwhEmr); 

    spinner = (Spinner) findViewById(R.id.spinner); 

    // Loading spinner data from database 
    SQLiteDatabase db = new DatabaseOpenHelper(this).getWritableDatabase(); 

    // Spinner Drop down elements 
    // List<String> lables = db.getAllLabels(); 
    Cursor c = db.rawQuery(
      "SELECT AccountID AS _id, ConsumerName FROM Consumers", null); 
    // Creating adapter for spinner 
    startManagingCursor(c); 
    String[] from = new String[] { "_id" }; 
    int[] to = new int[] { android.R.id.text1 }; 
    SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(this, 
      android.R.layout.simple_spinner_item, c, from, to); 

    // Drop down layout style - list view with radio button 
    dataAdapter 
      .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 

    // attaching data adapter to spinner 
    spinner.setAdapter(dataAdapter); 
    // set spinner listener to display the selected item id 
    mContext = this; 

    spinner.setOnItemSelectedListener(new OnItemSelectedListener() { 
     public void onItemSelected(AdapterView<?> parent, View view, 
       int position, long id) { 
      // On selecting a spinner item 
      //String label = parent.getItemAtPosition(position).toString(); 

      Cursor c = (Cursor) parent.getItemAtPosition(position); 
       mSpinnerSpeciesId = c.getInt(c 
       .getColumnIndexOrThrow("ConsumerName")); 


      // Showing selected spinner item 

     /* Toast.makeText(parent.getContext(), "You selected: " + label, 
        Toast.LENGTH_LONG).show();*/ 

     } 

     public void onNothingSelected(AdapterView<?> parent) { 
      // TODO Auto-generated method stub 
     } 
    }); 

    final Calendar ca = Calendar.getInstance(); 
    int yy = ca.get(Calendar.YEAR); 
    int mm = ca.get(Calendar.MONTH); 
    int dd = ca.get(Calendar.DAY_OF_MONTH); 
    dateTv.setText(new StringBuilder() 
      // Month is 0 based, just add 1 
      .append(yy).append(" ").append("-").append(mm + 1).append("-") 
      .append(dd)); 

    if (extras != null) { 

     rowID = extras.getLong("_id"); 
     // meterNoEt.setText(extras.getString("MeterNumber")); 
     // set current date into textview 
     // Spinner click listener 

     currentEt.setText(extras.getString("Current")); 
     previousEt.setText(extras.getString("Previous")); 
     kWhEt.setText(extras.getString("kWh")); 
     // dateTv.setText(extras.getString("Date")); 

    } 

    Button calButton = (Button) findViewById(R.id.calculateDef); 
    calButton.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 
      // TODO Auto-generated method stub 
      float result = Float.parseFloat(currentEt.getText().toString()) 
        - Float.parseFloat(previousEt.getText().toString()); 
      kWhEt.setText(Float.toString(result)); 

     } 

    }); 

    Button saveButton = (Button) findViewById(R.id.addConsumption); 

    saveButton.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 
      if (kWhEt.getText().length() != 0) { 

       AsyncTask<Object, Object, Object> saveContactTask = new AsyncTask<Object, Object, Object>() { 

        @Override 
        protected Object doInBackground(Object... params) { 

         saveContact(); 
         return null; 

        } 

        @Override 
        protected void onPostExecute(Object result) { 
         /* 
         * Intent addContact = new Intent(
         * ElectricMeterReader.this, 
         * ConsumerReadList.class); 
         * startActivity(addContact); 
         */ 
         finish(); 
        } 
       }; 

       saveContactTask.execute((Object[]) null); 

      } 

      else { 
       AlertDialog.Builder alert = new AlertDialog.Builder(
         ElectricMeterReader.this); 
       alert.setTitle(R.string.errorTitle); 
       alert.setMessage(R.string.errorMessage); 
       alert.setPositiveButton(R.string.errorButton, null); 
       alert.show(); 
      } 
     } 
    }); 
} 



public boolean onCreateOptionsMenu(Menu menu) { 
    super.onCreateOptionsMenu(menu); 
    MenuInflater inflater = getMenuInflater(); 
    inflater.inflate(R.menu.consumer_menu, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
    case R.id.addConsumerItem: 
     Intent addContact = new Intent(ElectricMeterReader.this, 
       AddEditConsumer.class); 
     startActivity(addContact); 
     return true; 

    case R.id.consumerInfo: 
     Intent electricMeterReader = new Intent(ElectricMeterReader.this, 
       ViewConsumer.class); 
     startActivity(electricMeterReader); 
     return true; 

    default: 
     return super.onOptionsItemSelected(item); 
    } 

} 

private void saveContact() { 

    DatabaseConnector dbConnector = new DatabaseConnector(this); 

    if (getIntent().getExtras() == null) { 

     dbConnector.insertConsumption(meterNoEt.getText().toString(), 
       currentEt.getText().toString(), previousEt.getText() 
         .toString(), kWhEt.getText().toString(), dateTv 
         .getText().toString(), 
       spinner.getItemAtPosition(mSpinnerSpeciesId).toString() 

     ); 

    } else { 
     dbConnector.updateConsumption(rowID, 
       currentEt.getText().toString(), previousEt.getText() 
         .toString(), kWhEt.getText().toString(), dateTv 
         .getText().toString(), 
       spinner.getItemAtPosition(mSpinnerSpeciesId).toString()); 

    } 
} 

}

插入方法編碼到我的databaseconnector

public void insertConsumption(String meter_number, String current, 
     String previous, String kWh, String date, String consumer_name) { 

    ContentValues newCons = new ContentValues(); 

    newCons.put("_id", meter_number); 
    newCons.put("Current", current); 
    newCons.put("Previous", previous); 
    newCons.put("kWh", kWh); 
    newCons.put("Date", date); 
    newCons.put("ConsumerName", consumer_name); 

    open(); 

    database.insert("Consumptions", null, newCons); 

    close(); 
} 

我的數據庫Openhelper

public class DatabaseOpenHelper extends SQLiteOpenHelper { 

    static final String dbName = "ElectricMeterDB"; 

    static final String tableLabels = "labels"; 
    static final String consumptionsTable = "Consumptions"; 
    static final String colMeterNumber = "_id"; 
    static final String colCurrent = "Current"; 
    static final String colPrevious = "Previous"; 
    static final String colkWh = "kWh"; 
    static final String colDate = "Date"; 
    static final String colConsumer = "ConsumerName"; 

    static final String consumersTable = "Consumers"; 
    static final String colAccountID = "AccountID"; 
    static final String colName = "ConsumerName"; 
    static final String colAddress = "Address"; 

    public static final String viewReads = "ViewReading"; 

    public DatabaseOpenHelper(Context context) { 
     super(context, dbName, null, 2); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

     db.execSQL("CREATE TABLE " + consumersTable + " (" + colAccountID 
      + " INTEGER PRIMARY KEY NOT NULL," + colName + " TEXT NOT NULL, " 
      + colAddress + " TEXT NOT NULL);"); 

    db.execSQL("CREATE TABLE " + consumptionsTable + " (" + colMeterNumber 
      + " INTEGER PRIMARY KEY NOT NULL," + colCurrent + " INTEGER, " 
      + colPrevious + " INTEGER, " + colkWh + " INTEGER, " + colDate 
      + " TEXT, " + colConsumer + " INTEGER NOT NULL, FOREIGN KEY (" 
      + colConsumer + ") REFERENCES " + consumersTable + " (" 
      + colAccountID + "));"); 

    db.execSQL("CREATE TRIGGER fk_cmpcons_consid" + " BEFORE INSERT " 
      + " ON " + consumptionsTable + " FOR EACH ROW BEGIN" 
      + " SELECT CASE WHEN ((SELECT " + colAccountID + " FROM " 
      + consumersTable + " WHERE " + colAccountID + " =new." 
      + colConsumer + ") IS NULL)" 
      + "THEN RAISE (ABORT, 'Foreign Key Violation') END;" + "END;"); 

    db.execSQL("CREATE VIEW " + viewReads + " AS SELECT " 
      + consumptionsTable + " . " + colMeterNumber + " AS _id, " 
      + consumptionsTable + " . " + colCurrent + " ," 
      + consumptionsTable + " . " + colPrevious + " ," 
      + consumptionsTable + " . " + colkWh + ", " + consumptionsTable 
      + " . " + colDate + "," + consumersTable + "." + colConsumer 
      + " FROM " + consumptionsTable + " JOIN " + consumersTable 
      + " ON " + consumptionsTable + " . " + colConsumer + " = " 
      + consumersTable + "." + colAccountID); 
    // Inserts pre-defined consumers 

} 

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

    db.execSQL("DROP TABLE IF EXISTS" + consumptionsTable); 
    db.execSQL("DROP TABLE IF EXISTS" + consumersTable); 

    db.execSQL("DROP TRIGGER IF EXISTS consumers_id_trigger"); 
    db.execSQL("DROP TRIGGER IF EXISTS consumers_id_trigger22"); 
    db.execSQL("DROP TRIGGER IF EXISTS fk_cmpcons_consid"); 
    db.execSQL("DROP VIEW IF EXISTS" + viewReads); 
    onCreate(db); 
} 

public void insertLabel(String label) { 

    SQLiteDatabase db = this.getWritableDatabase(); 

    ContentValues values = new ContentValues(); 
    values.put(colName, label); 

    // Inserting Row 
    db.insert(tableLabels, null, values); 
    db.close(); // Closing database connection 
} 

    /** 
    * Getting all labels returns list of labels 
    * */ 
    public List<String> getAllLabels() { 

     List<String> labels = new ArrayList<String>(); 

     // Select All Query 
     String selectQuery = "SELECT * FROM " + consumersTable; 

     SQLiteDatabase db = this.getReadableDatabase(); 
     Cursor cursor = db.rawQuery(selectQuery, null); 

     // looping through all rows and adding to list 
     if (cursor.moveToFirst()) { 
      do { 
       labels.add(cursor.getString(1)); 
      } while (cursor.moveToNext()); 
     } 

     // closing connection 
     cursor.close(); 
     db.close(); 

     // returning lables 
     return labels; 
    } 
} 

我被這個問題困住了。請幫幫我。感謝未來的迴應。

log.d

02-18 13:49:59.870: D/saveContact(30881): _id: 36698521 ConsumerName: [email protected] 

我arrayadapter;

public void arrayAdapterList() { 

    final String[] from = new String[] { DatabaseOpenHelper.colAccountID }; 
    // int[] to = new int[] { android.R.id.text1 }; 

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
      android.R.layout.simple_spinner_item, from); 
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
    spinner = (Spinner) findViewById(R.id.spinner); 
    // attaching data adapter to spinner 
    spinner.setAdapter(adapter); 

    spinner.setOnItemSelectedListener(new OnItemSelectedListener() { 
     public void onItemSelected(AdapterView<?> parent, View view, 
       int position, long id) { 
      // On selecting a spinner item 
      // String col= c.getString(c.getColumnIndex("_id")); 
      int item = spinner.getSelectedItemPosition(); 
      Toast.makeText(getBaseContext(), "You Selected: " + from[item], 
        Toast.LENGTH_SHORT).show(); 

     } 

     public void onNothingSelected(AdapterView<?> parent) { 
      // TODO Auto-generated method stub 
     } 
    }); 

} 

回答

8

好像要插入可能是NULL的NOT NULL字段(ConsumerName你的情況)或PK(在你的情況_id)已經存在一些值。錯誤代碼19意味着在操作(插入等)期間違反了表約束(NOT NULL,UNIQUE等)。以下是SQLITE Error Codes的列表

[email protected]是分配給ConsumerName的垃圾值。因此,請做一些解決方法,以便從遊標中獲取適當的FK for ConsumerName。

你的SimpleCursorAdapter有問題。所以請看看它。如果您在微調器中獲得了正確的值,那麼請從這個而不是spinner.getItemAtPosition(mSpinnerSpeciesId).toString()獲得spineer的選定值。

希望這可以幫助你。

+0

我試過把我的數據庫拉到sqlite瀏覽器,似乎沒有值添加到我的消費表中。我的代碼有問題嗎? – 2013-02-18 04:44:33

+0

我應該放什麼? ConsumerName或主鍵本身像AccountID?這是我的消費表中的外鍵。在數據庫瀏覽器插入正在工作。我曾嘗試過一次,我認爲它們彼此溝通,因爲外部關鍵字或消費者表的主鍵被列入我的消費表中,這就是爲什麼我創建微調到我的XML並填充AccountID希望這個問題將解決。 – 2013-02-18 05:02:59

+0

只需在插入之前嘗試打印ConsumerName,並確保從光標抽取正確的值並將其分配給適配器。 – 2013-02-18 05:03:09

1

約束失敗通常表明您做了類似於將空值傳遞到您在創建表格時聲明爲不爲null的列。

所以,刪除不爲空,並創建表時將空值。

1

我得到了同樣的錯誤,並通過在代碼中設置ID NULL來解決它。 由於ID是PK SqlLite會自動增加其值,因此不需要進行設置。

public void insertConsumption(String meter_number, String current, 
    String previous, String kWh, String date, String consumer_name) { 

    ContentValues newCons = new ContentValues(); 

    //newCons.put("_id", meter_number); 
    newCons.put("Current", current); 
    newCons.put("Previous", previous); 
    newCons.put("kWh", kWh); 
    newCons.put("Date", date); 
    newCons.put("ConsumerName", consumer_name); 

    open(); 

    database.insert("Consumptions", null, newCons); 

    close(); 
} 
0

你聲明的列「colAccountID」主鍵,所以SQLite的分貝拋出錯誤,而你想一次又一次地插入相同的ID。

相關問題