【问题标题】:Android unable to write datetime to sqllite databaseAndroid无法将日期时间写入sqlite数据库
【发布时间】:2015-06-14 20:34:30
【问题描述】:

我在我的应用中使用 Google Tasks API。我的应用程序“到期日”requires a DateTime object 中的一个字段。我使用 Android datepicker dailog 和 EditText 视图来捕获到期日期,然后将用户输入转换为日期时间格式。当我尝试写入我的 SQLite 数据库时,出现以下异常。

Error inserting due=2015-06-14T15:58:38.572-04:00 title=Test app _id=TaskId0.07429873487580996 status=needsAction notes=Test write
    android.database.sqlite.SQLiteException: table tasks has no column named due (code 1): , while compiling: INSERT INTO tasks(due,title,_id,status,notes) VALUES (?,?,?,?,?)

这很令人困惑,因为我确实定义了一个名为“due”的列。进一步在日志中有另一个例外。

06-14 15:58:38.607  15395-15395/com.github.idclark.forgetmenot E/EDITFRAGMENT﹕ null
    java.text.ParseException: Unparseable date: "06/14/15" (at offset 8)
            at java.text.DateFormat.parse(DateFormat.java:579)
            at com.github.idclark.forgetmenot.EditFragment.getTaskDueDate(EditFragment.java:64)

Schema 定义为

public static final class TaskEntry implements BaseColumns {

        public static final String TABLE_NAME = "tasks";
        public static final String COLUMN_TASK_ID = "_id";
        public static final String COLUMN_TASK_TITLE = "title";
        public static final String COLUMN_TASK_UPDATED = "updated";
        public static final String COLUMN_TASK_SELFLINK = "selfLink";
        public static final String COLUMN_TASK_PARENT = "parent";
        public static final String COLUMN_TASK_POSITION = "position";
        public static final String COLUMN_TASK_NOTES = "notes";
        public static final String COLUMN_TASK_STATUS = "status";
        public static final String COLUMN_TASK_DUE = "due";
        public static final String COLUMN_TASK_COMPLETED = "completed";
        public static final String COLUMN_TASK_DELETED = "deleted";
        public static final String COLUMN_TASK_HIDDEN = "hidden";

所以“到期”列确实存在。该表是由

创建的
@Override
    public void onCreate(SQLiteDatabase db) {

        //status must be either needsAction or completed

        final String CREATE_TASK_TABLE =
                "CREATE TABLE " + TaskEntry.TABLE_NAME + " (" +
                        TaskEntry._ID + " INTEGER PRIMARY KEY," +
                        TaskEntry.COLUMN_TASK_ID + "TEXT NOT NULL, " +
                        TaskEntry.COLUMN_TASK_TITLE + "TEXT NOT NULL, " +
                        TaskEntry.COLUMN_TASK_COMPLETED + "TEXT, " +
                        TaskEntry.COLUMN_TASK_NOTES + "TEXT, " +
                        TaskEntry.COLUMN_TASK_STATUS + "TEXT NOT NULL, " +
                        TaskEntry.COLUMN_TASK_DUE + "DATETIME, " +
                        TaskEntry.COLUMN_TASK_UPDATED + "DATETIME, " +
                        TaskEntry.COLUMN_TASK_PARENT + "TEXT, " +
                        TaskEntry.COLUMN_TASK_DELETED + "BOOLEAN, " +
                        TaskEntry.COLUMN_TASK_SELFLINK + "TEXT, " +
                        TaskEntry.COLUMN_TASK_POSITION + "TEXT, " +
                        TaskEntry.COLUMN_TASK_HIDDEN + "TEXT" + ")";

        db.execSQL(CREATE_TASK_TABLE);
    }

到期日转换发生在此方法中。

public DateTime getTaskDueDate() {
    mDueDate = (EditText) getActivity().findViewById(R.id.task_due_date);
    return new DateTime(mDueDate.getText().toString());
}

然后数据最终被写入数据库

public boolean insertRow(Task task) {
        ContentValues values = new ContentValues();
        values.put(TaskContract.TaskEntry.COLUMN_TASK_STATUS, task.getStatus());
        values.put(TaskContract.TaskEntry.COLUMN_TASK_ID,task.getId());
        values.put(TaskContract.TaskEntry.COLUMN_TASK_TITLE,task.getTitle());
        values.put(TaskContract.TaskEntry.COLUMN_TASK_DUE, task.getDue().toString());
        values.put(TaskContract.TaskEntry.COLUMN_TASK_NOTES, task.getNotes());

        SQLiteDatabase db = this.getWritableDatabase();
        boolean createSuccessful = db.insert(TaskContract.TaskEntry.TABLE_NAME, null, values) > 0;
        db.close();
        return createSuccessful;
    }

我对为什么这个写入失败感到困惑,并且 sql 声称没有“到期”列。即使存在解析异常,我也会在日志中看到时间戳。在将它写入数据库之前,我在 datetime 对象上调用 .toString() 是问题的一部分吗?我没有很多 sql 经验,并且对如何处理这些异常感到非常困惑。

【问题讨论】:

  • 你在这方面有什么收获吗?我还认为调用 toString() 是个问题。
  • @burntsugar 没有仍然卡住,虽然我很确定这是日期解析 + 将日期时间条目添加到 ContentValues 对象的组合
  • hrmmm,sqlite 没有日期时间类型sqlite.org/datatype3.html。我必须将该时间戳转换为文本
  • 您的解析错误与 sqlite 错误无关。您正在使用默认的 SimpleDateFormat 来解析您的字符串,该字符串使用您的语言环境的默认格式,这可能与您传入的日期的模式不匹配。如果您总是在月/日/年中传递,您应该通过传入“MM/dd/yy”作为模式显式设置您的 SimpleDateFormat。
  • @joep 我已经更新了将日期对象解析为 DateTime 对象的方法,但是现在的例外是 java.lang.NumberFormatException: Invalid date/time format: 06/15/15。正确格式化日期的任何提示?

标签: java android sqlite datetime


【解决方案1】:

对于 sqlite 问题,您需要在列名和类型之间有空格。例如,改变

TaskEntry.COLUMN_TASK_DUE + "DATETIME, " +

TaskEntry.COLUMN_TASK_DUE + " DATETIME, " +

几乎所有列都存在类似问题。

修复CREATE TABLE SQL 后,卸载并重新安装您的应用以重新创建数据库。

对于日期解析问题,请使用与您的数据匹配的日期格式。如果您需要详细的帮助,请发布一个新问题。

【讨论】:

  • 嗯,这是一个令人尴尬的简单修复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 2010-12-28
  • 1970-01-01
  • 2020-08-03
相关资源
最近更新 更多