Android应用向SQLite插入日期时间失败:报语法错误
问题分析与解决方案
你遇到的语法错误根源很明确:字符串类型的时间、日期值没有用单引号包裹,SQLite解析时会把21:05当成无效的语法结构,自然抛出near ":05": syntax error的报错。
快速修复:给字符串值添加单引号
先看你生成的错误SQL语句:
INSERT into calories values( 10, 21:05 , 2018-05-30);
表结构里mtime和mdate都是varchar类型,属于字符串,SQL语法要求这类值必须用单引号括起来。修改你的插入语句拼接逻辑,给时间和日期加上单引号:
time = FetchTime(); date = FetchDate(); System.out.println( time+" <--> "+date); // 给time和date添加单引号包裹 String insert_stmt = "INSERT into "+ msg.toString()+" values( "+ Integer.parseInt(msg1)+", '"+time+"' , '"+date+"');"; SQLiteDatabase db = dbhelper.getWritableDatabase(); db.execSQL(insert_stmt);
修复后生成的SQL就变成合法格式了:
INSERT into calories values( 10, '21:05' , '2018-05-30');
更安全规范的方案:使用参数化查询(强烈推荐)
直接拼接SQL字符串不仅容易出语法问题,还存在SQL注入风险。SQLite官方推荐用ContentValues或带占位符的查询来操作数据,示例如下:
方式1:用ContentValues插入
time = FetchTime(); date = FetchDate(); SQLiteDatabase db = dbhelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("mvalue", Integer.parseInt(msg1)); values.put("mtime", time); values.put("mdate", date); // 插入数据,返回值是新插入行的ID(失败返回-1) long insertId = db.insert(msg.toString(), null, values);
方式2:用占位符的execSQL
time = FetchTime(); date = FetchDate(); SQLiteDatabase db = dbhelper.getWritableDatabase(); // 用?作为占位符,明确指定字段顺序更清晰 String insertStmt = "INSERT into "+ msg.toString()+" (mvalue, mtime, mdate) values(?, ?, ?);"; // 传入占位符对应的参数数组,自动处理类型和引号 db.execSQL(insertStmt, new Object[]{Integer.parseInt(msg1), time, date});
这两种方式都不需要手动处理单引号,既避免了语法错误,又从根源上防止SQL注入,是更专业的数据库操作方式。
另外提醒个小细节:你的FetchTime方法里,SimpleDateFormat用了HH:MM——这里的MM代表月份,如果你想获取分钟,应该改成小写的mm,不然时间会显示错误的分钟值(比如把5月当成5分钟):
String FetchTime() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); // 把MM改成mm String time = sdf.format(new Date()); return time; }
内容的提问来源于stack exchange,提问作者Love Babbar
相关产品推荐
相关产品推荐

