2013-10-29 32 views
0

我在SQLite中創建了一個表'PLAN',並將'NAME'列設置爲TEXT NOT NULL,我試着用EditText中的值插入到表中。當EditText沒有值,我點擊提交時,該值作爲空字符串插入到列中。發生什麼事?我已經創建瞭如下的簡單數據驗證,但仍然插入了空值。我使用ContentValues來執行查詢。爲什麼Android仍然在SQLite的NOT NULL列中輸入空/空字符串?

DatabaseHelper

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

public class DatabaseHelper extends SQLiteOpenHelper { 
// Logcat tag 
public static final String LOG = "SODatabaseHelper"; 

// Database Version 
public static final int DATABASE_VERSION = 1; 

// Database Name 
public static final String DATABASE_NAME = "Planner.db"; 

// Table Names - column names 
public static final String TABLE_PLAN = "Plan"; 
public static final String TABLE_CATEGORY = "Category"; 
public static final String TABLE_GEAR = "Gear"; 
public static final String TABLE_GEARSET = "GearSet"; 
public static final String TABLE_GEARSETSHAVEGEAR = "GearSetsHaveGear"; 
public static final String TABLE_PLANHAVEGEAR = "PlanHaveGear"; 

// PLAN Table - column names 
public static final String KEY_PLANID = "planID"; 
public static final String COLUMN_PLANCATID = "planCatID"; 
public static final String COLUMN_PLANNAME = "planName"; 
public static final String COLUMN_PLANLOCATION = "planLocation"; 
public static final String COLUMN_DATECREATED = "planCreated"; 
public static final String COLUMN_PLANSUMMARY = "planSummary"; 
public static final String COLUMN_DATESTART = "planStart"; 
public static final String COLUMN_DATEEND = "planEnd"; 

// CATEGORY - column names 
public static final String KEY_CATID = "catID"; 
public static final String COLUMN_CATNAME = "catName"; 
public static final String COLUMN_CATDESC = "catDescription"; 

// GEAR Table - column names 
public static final String KEY_GEARID = "gearID"; 
public static final String COLUMN_GEARNAME = "gearName"; 
public static final String COLUMN_GEARDESC = "gearDescription"; 

// GEARSET Table - column names 
public static final String KEY_GEARSETID = "gearSetID"; 
public static final String COLUMN_GEARSETNAME = "gearSetName"; 
public static final String COLUMN_GEARSETDESC = "gearSetDescription"; 

// PLANHAVEGEARSET Table - column names 
public static final String KEY_PHG_PLANID = "phgPlanID"; 
public static final String KEY_PHG_GEARSETID = "phgGearSetID"; 

// GEARSETHAVEGEAR Table - column names 
public static final String KEY_GHG_GEARSETID = "ghgGearSetID"; 
public static final String KEY_GHG_GEARID = "ghgGearID"; 

public DatabaseHelper(Context context) { 
    super(context, DATABASE_NAME, null, DATABASE_VERSION); 
} 

// TABLE CREATIONS 
private static final String CREATE_TABLE_PLAN = "CREATE TABLE " 
     + TABLE_PLAN + "(" 
     + KEY_PLANID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
     + COLUMN_PLANCATID + " INTEGER NOT NULL, " 
     + COLUMN_PLANNAME + " TEXT NOT NULL, " 
     + COLUMN_PLANLOCATION + " TEXT NULL, " 
     + COLUMN_DATECREATED + " STRING NOT NULL, " 
     + COLUMN_PLANSUMMARY + " TEXT NULL, " 
     + COLUMN_DATESTART + " STRING NULL, " 
     + COLUMN_DATEEND + " STRING NULL" + ")"; 

private static final String CREATE_TABLE_CATEGORY = "CREATE TABLE " 
     + TABLE_CATEGORY + "(" 
     + KEY_CATID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
     + COLUMN_CATNAME + " TEXT NOT NULL, " 
     + COLUMN_CATDESC + " TEXT NULL" + ")"; 

private static final String CREATE_TABLE_GEAR = "CREATE TABLE " 
     + TABLE_GEAR + "(" 
     + KEY_GEARID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
     + COLUMN_GEARNAME + " TEXT NOT NULL, " 
     + COLUMN_GEARDESC + " TEXT NULL" + ")"; 

private static final String CREATE_TABLE_GEARSET = "CREATE TABLE " 
     + TABLE_GEARSET + "(" 
     + KEY_GEARSETID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
     + COLUMN_GEARSETNAME + " TEXT NOT NULL, " 
     + COLUMN_GEARSETDESC + "TEXT NULL" + ")"; 

private static final String CREATE_TABLE_GEARSETHAVEGEAR = "CREATE TABLE " 
     + TABLE_GEARSETSHAVEGEAR + "(" 
     + KEY_GHG_GEARID + " INTEGER NOT NULL, " 
     + KEY_GHG_GEARSETID + " INTEGER NOT NULL" + ")"; 

private static final String CREATE_TABLE_PLANHAVEGEARSET = "CREATE TABLE " 
     + TABLE_PLANHAVEGEAR + "(" 
     + KEY_PHG_PLANID + " INTEGER NOT NULL, " 
     + KEY_PHG_GEARSETID + " INTEGER NOT NULL" + ")"; 

@Override 
public void onCreate(SQLiteDatabase db) { 
    // creating required tables 
    db.execSQL(CREATE_TABLE_PLAN); 
    db.execSQL(CREATE_TABLE_CATEGORY); 
    db.execSQL(CREATE_TABLE_GEAR); 
    db.execSQL(CREATE_TABLE_GEARSET); 
    db.execSQL(CREATE_TABLE_PLANHAVEGEARSET); 
    db.execSQL(CREATE_TABLE_GEARSETHAVEGEAR); 
} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    Log.w(DatabaseHelper.class.getName(), 
      "UPDATING DATABASE FROM VERSION " + oldVersion + " TO VERSION " + newVersion 
        + " WHICH DESTROY ALL DATA."); 

    // on upgrade drop older tables 
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_PLAN); 
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_CATEGORY); 
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_GEAR); 
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_GEARSET); 
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_GEARSETSHAVEGEAR); 
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_PLANHAVEGEAR); 

    // create new tables 
    onCreate(db); 
} 
// TODO: Create each object data source class 
} 

計劃Datasource類

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 

import org.joda.time.DateTime; 

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

public class PlanDataSource { 
private SQLiteDatabase db; 
private DatabaseHelper databaseHelper; 
private String[] allColumns = { 
     DatabaseHelper.KEY_PLANID, 
     DatabaseHelper.COLUMN_PLANCATID, 
     DatabaseHelper.COLUMN_PLANNAME, 
     DatabaseHelper.COLUMN_PLANLOCATION, 
     DatabaseHelper.COLUMN_DATECREATED, 
     DatabaseHelper.COLUMN_PLANSUMMARY, 
     DatabaseHelper.COLUMN_DATESTART, 
     DatabaseHelper.COLUMN_DATEEND 
}; 

/** 
* PlanDataSource constructor 
* @param context Context 
*/ 
public PlanDataSource(Context context) { 
    databaseHelper = new DatabaseHelper(context); 
} 

public void open() throws SQLException { 
    db = databaseHelper.getWritableDatabase(); 
} 

public void close() { 
    databaseHelper.close(); 
} 

/** 
* Method for inserting new plan to the database 
* @param newPlan plan class object, as Plan 
* @return true if the plan successfully inserted to database 
* @throws android.database.SQLException if there are invalid input 
*/ 
public Boolean insertPlan(Plan newPlan) { 
    ContentValues contentPlan = new ContentValues(); 

    contentPlan.put(DatabaseHelper.COLUMN_PLANCATID, newPlan.getCatId()); 
    contentPlan.put(DatabaseHelper.COLUMN_PLANNAME, newPlan.getName()); 
    contentPlan.put(DatabaseHelper.COLUMN_PLANLOCATION, newPlan.getDestination()); 
    contentPlan.put(DatabaseHelper.COLUMN_DATECREATED, newPlan.getCreated().toString()); 
    contentPlan.put(DatabaseHelper.COLUMN_PLANSUMMARY, newPlan.getSummary()); 

    if (newPlan.getStart() != null) { 
     contentPlan.put(DatabaseHelper.COLUMN_DATESTART, 
       newPlan.getStart().toString()); 
    } 

    if (newPlan.getEnd() != null) { 
     contentPlan.put(DatabaseHelper.COLUMN_DATEEND, 
       newPlan.getEnd().toString()); 
    } 

    try { 
     db.insert(DatabaseHelper.TABLE_PLAN, null, contentPlan); 
     return true; 

    } catch (SQLiteException ex) { 
     throw new SQLiteException("Error performing insertPlan()"); 
    } finally { 
     db.close(); 
    } 
} 

/** 
* Method for deleting one plan based on its id 
* @param planId primary key of the plan 
* @return true if plan is successfully deleted 
* @throws android.database.SQLException if there is an error 
*/ 
public Boolean deletePlan(int planId) { 
    try { 
     /** try delete from TABLE_PLAN */ 
     db.delete(
       DatabaseHelper.TABLE_PLAN, 
       DatabaseHelper.KEY_PLANID + "=" + planId, 
       null); 

     /** returning true value is the action is success */ 
     return true; 
    } catch (SQLException ex) { 
     /** throw the exception */ 
     throw new SQLException("Error performing deletePlan()"); 
    } finally { 
     /** close the database connection */ 
     db.close(); 
    } 
} 

/** 
* Method to get all plan from the database 
* @return List of all Plan from the database 
*/ 
public List<Plan> getAllPlans() { 
    List<Plan> planList = new ArrayList<Plan>(); 

    Cursor cursor = db.query(DatabaseHelper.TABLE_PLAN, 
      allColumns, null, null, null, null, null); 

    cursor.moveToFirst(); 
    while (!cursor.isAfterLast()) { 
     Plan plan = cursorToPlan(cursor); 
     planList.add(plan); 
     cursor.moveToNext(); 
    } 

    /** closing the database connection */ 
    cursor.close(); 

    /** return the list */ 
    return planList; 
} 

public Plan getPlan(int planId) { 
    Plan plan = null; 
    Cursor cursor = db.query(
      DatabaseHelper.TABLE_PLAN, 
      allColumns, 
      DatabaseHelper.KEY_PLANID + "=?", 
      new String[]{String.valueOf(planId)}, 
      null, null, null, "1"); 

    cursor.moveToFirst(); 
    if (!cursor.isAfterLast()) { 
     plan = cursorToPlan(cursor); 
    } 

    /** closing the database connection */ 
    db.close(); 
    cursor.close(); 

    /** return the plan */ 
    return plan; 
} 

/** 
* Method to convert from cursor object to Plan object 
* @param cursor the database query adapter 
* @return Plan class object based information from the cursor 
*/ 
private Plan cursorToPlan(Cursor cursor) { 
    return new Plan(
      cursor.getInt(0), 
      cursor.getInt(1), 
      cursor.getString(2), 
      cursor.getString(3), 
      new DateTime(cursor.getString(4)), 
      cursor.getString(5), 
      new DateTime(cursor.getString(6)), 
      new DateTime(cursor.getString(7)) 
    ); 
} 
} 

這是從視圖

case R.id.action_planeditor_saveplan: 
      planDataSource = new PlanDataSource(PlanEditorActivity.this); 
      planDataSource.open(); 

      try { 
       Plan newPlan = new Plan(
        Integer.valueOf(
          planCategorySpinner.getSelectedItem().toString()), 
        planNameEditText.getText().toString(), 
        planLocationEditText.getText().toString(), 
        DateTime.now(), 
        planSummaryEditText.getText().toString(), 
        startDate, 
        endDate); 

       planDataSource.insertPlan(newPlan); 
       Toast.makeText(PlanEditorActivity.this, "Success", Toast.LENGTH_SHORT).show(); 
       setResult(1, null); 
       finish(); 
       return true; 

      } catch (SQLiteException ex) { 
       Toast.makeText(getBaseContext(), ex.getMessage(), Toast.LENGTH_LONG).show(); 
       return false; 
      } finally { 
       planDataSource.close(); 
      } 


public void setName(String name) { 
    if (name.trim().equals("") || name.isEmpty()) 
     this.name = null; 
    this.name = name; 
} 

請幫忙找回價值。

回答

1

你總是仍然接受String name的論點。

當給出空名稱時,您在NULL上設置this.name,但在此之後它將繼續使用this.name = name;不過。

您應該嘗試在if/else結構中添加適當的括號,以使其更清楚自己和他人;

你想要的是像這樣

public void setName(String name) { 
    if(name.trim().equals("") || name.isEmpty()){ 
     this.name = null; 
    }else{ 
     this.name = name; 
    } 
} 
+0

聖****,傻我!謝謝! – robotboy

+0

@Stefan de Bruijn:將NULL或一串「」添加到數據庫而不是空字符串是否有好處?我發佈了這個問題,我仍然在尋找答案:http://stackoverflow.com/questions/38152012/android-sqlite-will-a-blank-row-cause-any-database-issues – AJW

0

你的列名定義爲NOT NULL。所以當你的EditText沒有任何價值時,你別無選擇,只能將它存儲爲空字符串。

如果您的意圖是將空字符串存儲爲NULL,則需要從列定義中刪除NOT NULL。然後,當您設置ContentValues時,請檢查您要保存的字符串。如果爲空或空的,而不是使用:

contentPlan.putNull(DatabaseHelper.COLUMN_PLANNAME); 

還要注意的是一個空字符串不是一個空值就SQLite的關注。一個空字符串仍然是一個字符串,並計爲文本。有NOT NULL只是意味着你不能根據上面的語句將它設置爲NULL,或者在插入時不給它賦值。

+0

嗯,這是一些有用的信息! :)我不知道關於putNull也許我可以稍後再嘗試,因爲現在我的數據驗證使用了不同的方法。 – robotboy

+0

@NigelK:是否有一個好處是有NULL或一個「」字符串添加到數據庫,而不是一個空字符串?我在下面的鏈接發佈了這個問題,我仍然在尋找答案:http://stackoverflow.com/questions/38152012/android-sqlite-will-a-blank-row-cause-any-database-issues – AJW

+1

@AJW一個空字符串和「」是一樣的。存儲空字符串會佔用少量空間,而null不會。這一切都取決於你想要列的內容來表示。空表示沒有設置值。另一方面,空字符串是一個設置值(它是一個字符串,與其他任何字符串一樣,雖然沒有字符)。如果在你的數據模型中一個空字符串確實表明沒有設置值,那麼使用null在概念上是一個更好的選擇。 – NigelK

相關問題