为什么Android仍然在SQLite的NOTNULL列中输入null/空字符串?

为什么Android仍然在SQLite的NOTNULL列中输入null/空字符串?,android,sqlite,Android,Sqlite,我在SQLite中创建了一个表“PLAN”,并将列“NAME”设置为TEXT NOT NULL,我尝试使用EditText中的值插入该表。当EditText没有值并且我单击submit时,该值将作为空字符串插入到列中。发生了什么事?我创建了如下的简单数据验证,但仍然插入了空值。我使用ContentValues来执行查询 数据库助手 import android.content.Context; import android.database.sqlite.SQLiteDatabase; impo

我在SQLite中创建了一个表“PLAN”,并将列“NAME”设置为TEXT NOT NULL,我尝试使用EditText中的值插入该表。当EditText没有值并且我单击submit时,该值将作为空字符串插入到列中。发生了什么事?我创建了如下的简单数据验证,但仍然插入了空值。我使用ContentValues来执行查询

数据库助手

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
}
计划数据源类

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))
    );
}
}

请提供帮助。

您始终接受参数
字符串名

当给出一个空名称时,您将
this.name
设置为
NULL
,但之后它将继续使用
this.name=name
;不过

你应该尝试在if/else结构中添加适当的括号,以便让你自己和他人更清楚

你想要的是这样的东西

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

您的列名被定义为非空。因此,当EditText没有值时,您别无选择,只能将其存储为空字符串

如果您的目的是将空字符串存储为NULL,则需要从列定义中删除NOTNULL。然后,在设置ContentValue时,检查要保存的字符串。如果为null或空,请改用此选项:

contentPlan.putNull(DatabaseHelper.COLUMN_PLANNAME);

还要注意,就SQLite而言,空字符串不是空值。空字符串仍然是字符串并计为文本。拥有NOTNULL仅仅意味着不能按照上面的语句将其设置为NULL或在insert中不给它任何值。

这是一些有用的信息!:)我不知道putNull,也许我可以稍后再试,因为目前我的数据验证使用的是不同的方法。@NigelK:将NULL或“”字符串添加到数据库中而不是空字符串有什么好处吗?我在下面的链接上发布了这个问题,现在仍在寻找答案:@AJW是一个空字符串,而“”是同一个东西。存储空字符串会占用少量空间,而null则不会。这完全取决于您希望列的内容表示什么。Null表示未设置任何值。另一方面,空字符串是一个集合值(它是一个字符串,与任何其他字符串一样,尽管其中没有字符)。如果在您的数据模型中,空字符串确实表示未设置任何值,则从概念上讲,使用null是更好的选择。@Stefan de Bruijn:将null或“”字符串添加到数据库中而不是空字符串有什么好处吗?我发布了这个问题,仍在寻找答案:
contentPlan.putNull(DatabaseHelper.COLUMN_PLANNAME);