android.database.sqlite.SQLiteException:表contact_data没有名为timestamp_的列
Posted
技术标签:
【中文标题】android.database.sqlite.SQLiteException:表contact_data没有名为timestamp_的列【英文标题】:android.database.sqlite.SQLiteException: table contact_data has no column named timestamp_ 【发布时间】:2011-06-13 22:30:14 【问题描述】:嗯,我想做的是在第一次安装时更新我的应用程序。所以在第一次访问时,我的应用程序有一个访问 CallLog 的服务,并检索所有数据并插入到应用程序数据库中。
我有一列timestamp_
,我想插入通话的时间戳。但是当我尝试插入时,它说该表没有名为 timestamp_ 的列,并且在 sql 字符串中明确写入了该列的名称。我不知道为什么要这样做。
我的 CREATE TABLE 字符串写在 strings.xml
中,我访问该字符串并将其拆分为每一行。
这里是Service的代码,SQL字符串,然后是DataHandlerDB的代码,它有创建DB的方法。
我的服务:
package com.myapp.test;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.rogercg.phonestatistics.CallDataHelper.OpenHelper;
import android.app.Service;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.provider.Contacts;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.Toast;
public class RatedCallsService extends Service
private static final String LOG_TAG = "RatedCallsService";
private Handler handler = new Handler();
private SQLiteDatabase db;
private OpenHelper helper;
private String theDate;
private String theMonth_;
private String theYear_;
private String theDay_;
public static boolean servReg = false;
class RatedCallsContentObserver extends ContentObserver
public RatedCallsContentObserver(Handler h)
super(h);
helper = new OpenHelper(getApplicationContext());
db = helper.getWritableDatabase();
Log.i(LOG_TAG, "constructor");
@Override
public boolean deliverSelfNotifications()
Log.i(LOG_TAG, "deliver self");
return true;
@Override
public void onChange(boolean selfChange)
super.onChange(selfChange);
Log.i(LOG_TAG, "selfchange " + selfChange);
searchInsert();
@Override
public void onCreate()
servReg = true;
helper = new OpenHelper(getApplicationContext());
db = DataHandlerDB.createDB(this);
registerContentObserver();
Cursor dbsize = DataHandlerDB.selectTopCalls(this
.getApplicationContext());
if (dbsize.getCount() == 0)
Toast.makeText(this.getApplicationContext(), "Updating Database.",
Toast.LENGTH_LONG).show();
Log.i(LOG_TAG, "Atualizou " + dbsize.getCount());
updateDB();
Cursor currsize = DataHandlerDB.selectTopCalls(this
.getApplicationContext());
currsize.moveToFirst();
Log.i(LOG_TAG, "cursize " + currsize.getCount());
@Override
public void onDestroy()
super.onDestroy();
db.close();
this.getApplicationContext()
.getContentResolver()
.unregisterContentObserver(
new RatedCallsContentObserver(handler));
servReg = false;
@Override
public IBinder onBind(Intent arg0)
return null;
protected void searchInsert()
Cursor cursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DATE + " DESC ");
if (cursor.moveToFirst())
int numberColumnId = cursor
.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int durationId = cursor
.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int contactNameId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
int numTypeId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);
int callTypeId = cursor
.getColumnIndex(android.provider.CallLog.Calls.TYPE);
int dateColumnId = cursor
.getColumnIndex(android.provider.CallLog.Calls.DATE);
Date dt = new Date();
int hours = dt.getHours();
int minutes = dt.getMinutes();
int seconds = dt.getSeconds();
String currTime = hours + ":" + minutes + ":" + seconds;
SimpleDateFormat dateFormat = new SimpleDateFormat("M/d/yyyy");
Date date = new Date();
cursor.moveToFirst();
String contactNumber = cursor.getString(numberColumnId);
String contactName = (null == cursor.getString(contactNameId) ? ""
: cursor.getString(contactNameId));
String duration = cursor.getString(durationId);
String numType = cursor.getString(numTypeId);
String callType = cursor.getString(callTypeId);
String dateColumn = cursor.getString(dateColumnId);
seconds = Integer.parseInt(duration);
theDate = dateFormat.format(date);
if (theDate.length() == 9)
theMonth_ = theDate.substring(0, 1);
theDay_ = theDate.substring(2, 4);
theYear_ = theDate.substring(5, 9);
else if (theDate.length() == 10)
theMonth_ = theDate.substring(0, 2);
theDay_ = theDate.substring(3, 4);
theYear_ = theDate.substring(6, 10);
else if (theDate.length() == 8)
theMonth_ = theDate.substring(0, 1);
theDay_ = theDate.substring(2, 3);
theYear_ = theDate.substring(4, 8);
ContentValues values = new ContentValues();
ContentValues values2 = new ContentValues();
values.put("contact_id", 1);
values.put("contact_name", contactName);
values.put("number_type", numType);
values.put("contact_number", contactNumber);
values.put("duration", Utilities.convertTime(seconds));
values.put("date", dateFormat.format(date));
values.put("timestamp_", dateColumn);
values.put("current_time", currTime);
values.put("cont", 1);
values.put("type", callType);
values2.put("month",
Utilities.monthName(Integer.parseInt(theMonth_)));
values2.put("duration", Utilities.convertTime(seconds));
values2.put("year", theYear_);
values2.put("month_num", Integer.parseInt(theMonth_));
if (!db.isOpen())
db = getApplicationContext()
.openOrCreateDatabase(
"/data/data/com.myapp.test/databases/calls.db",
SQLiteDatabase.OPEN_READWRITE, null);
if (duration != "")
if (Integer.parseInt(duration) != 0)
String existingMonthDuration = DataHandlerDB
.selectMonthsDuration(theMonth_, theYear_, this);
Integer newMonthDuration;
// Verifica se ja existe mes no MONTHS_DUR
if (existingMonthDuration != "")
newMonthDuration = Integer
.parseInt(existingMonthDuration)
+ Integer.parseInt(duration);
values2.put("duration",
Utilities.convertTime(newMonthDuration));
db.update(DataHandlerDB.MONTHS_DUR, values2,
"year = ?", new String[] theYear_ );
else
db.insert(DataHandlerDB.MONTHS_DUR, null, values2);
Cursor c = DataHandlerDB.selectTimeStamp(this
.getApplicationContext());
if (c.moveToFirst())
Log.i(LOG_TAG, "c.getstr8: " + c.getString(8));
if (!c.getString(8).equals(dateColumn))
Log.i(LOG_TAG, "Antes do db.insert line 202");
db.insert(DataHandlerDB.CONTACT_DATA, null, values);
cursor.close();
protected void updateDB()
Cursor cursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
null);
cursor.moveToFirst();
do
int numberColumnId = cursor
.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int durationId = cursor
.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int contactNameId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
int numTypeId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);
int callTypeId = cursor
.getColumnIndex(android.provider.CallLog.Calls.TYPE);
int dateColumnId = cursor
.getColumnIndex(android.provider.CallLog.Calls.DATE);
Date dt = new Date();
int hours = dt.getHours();
int minutes = dt.getMinutes();
int seconds = dt.getSeconds();
String currTime = hours + ":" + minutes + ":" + seconds;
SimpleDateFormat dateFormat = new SimpleDateFormat("M/d/yyyy");
Date date = new Date();
String contactNumber = cursor.getString(numberColumnId);
String contactName = (null == cursor.getString(contactNameId) ? ""
: cursor.getString(contactNameId));
String duration = cursor.getString(durationId);
String numType = cursor.getString(numTypeId);
String callType = cursor.getString(callTypeId);
String dateColumn = cursor.getString(dateColumnId);
seconds = Integer.parseInt(duration);
theDate = dateFormat.format(date);
if (theDate.length() == 9)
theMonth_ = theDate.substring(0, 1);
theDay_ = theDate.substring(2, 4);
theYear_ = theDate.substring(5, 9);
else if (theDate.length() == 10)
theMonth_ = theDate.substring(0, 2);
theDay_ = theDate.substring(3, 4);
theYear_ = theDate.substring(6, 10);
else if (theDate.length() == 8)
theMonth_ = theDate.substring(0, 1);
theDay_ = theDate.substring(2, 3);
theYear_ = theDate.substring(4, 8);
ContentValues values = new ContentValues();
ContentValues values2 = new ContentValues();
values.put("contact_id", 1);
values.put("contact_name", contactName);
values.put("number_type", numType);
values.put("contact_number", contactNumber);
values.put("duration", Utilities.convertTime(seconds));
values.put("date", dateFormat.format(date));
values.put("timestamp_", dateColumn);
values.put("current_time", currTime);
values.put("cont", 1);
values.put("type", callType);
values2.put("month",
Utilities.monthName(Integer.parseInt(theMonth_)));
values2.put("duration", Utilities.convertTime(seconds));
values2.put("year", theYear_);
values2.put("month_num", Integer.parseInt(theMonth_));
if (!db.isOpen())
db = getApplicationContext()
.openOrCreateDatabase(
"/data/data/com.myapp.test/databases/calls.db",
SQLiteDatabase.OPEN_READWRITE, null);
if (duration != "")
if (Integer.parseInt(duration) != 0)
String existingMonthDuration = DataHandlerDB
.selectMonthsDuration(theMonth_, theYear_, this);
Integer newMonthDuration;
// Verifica se ja existe mes no MONTHS_DUR
if (existingMonthDuration != "")
newMonthDuration = Integer
.parseInt(existingMonthDuration)
+ Integer.parseInt(duration);
values2.put("duration",
Utilities.convertTime(newMonthDuration));
db.update(DataHandlerDB.MONTHS_DUR, values2,
"year = ?", new String[] theYear_ );
else
db.insert(DataHandlerDB.MONTHS_DUR, null, values2);
db.insert(DataHandlerDB.CONTACT_DATA, null, values);
while (cursor.moveToNext());
cursor.close();
public void registerContentObserver()
Log.i(LOG_TAG, "Registrou ContentObserver");
this.getApplicationContext()
.getContentResolver()
.registerContentObserver(
android.provider.CallLog.Calls.CONTENT_URI, true,
new RatedCallsContentObserver(handler));
我的 DataHandlerDB。(处理数据库):
public class DataHandlerDB
private static final String DATABASE_NAME = "calls.db";
private static final int DATABASE_VERSION = 1;
protected static final String RATED_CONTACTS = "rated_contacts";
protected static final String CONTACT_DATA = "contact_data";
protected static final String MONTHS_DUR = "months_dur";
private static final String LOG_TAG = "DataHandlerDB";
protected static String CONTACT__ID_COL = "_id";
protected static String CONTACT_NAME_COL = "contact_name";
protected static String CONTACT_NUMBER_COL = "contact_number";
protected static String CONTACT_DURATION_COL = "duration";
protected static String CONTACT_DATE_COL = "date";
protected static String CONTACT_MONTH_COL = "month";
// create the DB
public static SQLiteDatabase createDB(Context ctx)
OpenHelper helper = new OpenHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
helper.onCreate(db);
helper.onOpen(db);
db.close();
return db;
public static class OpenHelper extends SQLiteOpenHelper
private final Context mContext;
OpenHelper(Context context)
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.mContext = context;
@Override
public void onCreate(SQLiteDatabase db)
String[] sql = mContext.getString(
R.string.My_OnCreate).split("\n");
db.beginTransaction();
try
Log.i(LOG_TAG, "entrou no try");
execMultipleSQL(db, sql);
db.setTransactionSuccessful();
catch (SQLException e)
Log.e("Error creating tables and debug data ", e.toString());
throw e;
finally
db.endTransaction();
private void execMultipleSQL(SQLiteDatabase db, String[] sql)
for (String s : sql)
if (s.trim().length() > 0)
db.execSQL(s);
Log.i(LOG_TAG, "Str sql " + s);
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
/*
* Log.w("RatedContacts Database",
* "Upgrading database, this will drop tables and recreate.");
* db.execSQL("DROP TABLE IF EXISTS " + RATED_CONTACTS); onCreate(db);
*/
@Override
public void onOpen(SQLiteDatabase db)
super.onOpen(db);
SQL 字符串(在 strings.xml 中声明):
<string name="My_OnCreate">
"CREATE TABLE IF NOT EXISTS contact_data ( _id INTEGER PRIMARY KEY AUTOINCREMENT, contact_id INTEGER, contact_name VARCHAR(50), number_type VARCHAR(50), contact_number VARCHAR(50), duration TIME, duration_sum TIME, date DATE, timestamp_ VARCHAR(50), current_time TIME, cont INTEGER, type VARCHAR(50), month VARCHAR(50), day VARCHAR(50), year VARCHAR(50) );
CREATE TABLE IF NOT EXISTS rated_contacts ( _id INTEGER PRIMARY KEY AUTOINCREMENT, contact_id INTEGER, contact_name VARCHAR(50), number_type VARCHAR(50), contact_number VARCHAR(50), duration TIME, duration_sum TIME, date DATE, timestamp_ VARCHAR(50), current_time TIME, cont INTEGER, type VARCHAR(50), month VARCHAR(50), day VARCHAR(50), year VARCHAR(50) );
CREATE TABLE IF NOT EXISTS months_dur ( _id INTEGER PRIMARY KEY AUTOINCREMENT, month VARCHAR(50), duration TIME, year VARCHAR(250), month_num INTEGER );"
</string>
这是来自 LogCat 的错误:
06-13 18:58:05.041: 信息/数据库(2121):sqlite 返回: 错误代码 = 1,味精 = 表 contact_data 没有名为的列 时间戳_
06-13 18:58:05.081: 错误/数据库(2121):插入错误 联系人号码=1234545 持续时间=00:00:05 contact_id=1 时间戳_=1307928304514 number_type=0 联系人姓名= current_time=18:58:4 类型=2 续=1 日期=6/13/2011 06-13 18:58:05.081:
错误/数据库(2121): android.database.sqlite.SQLiteException: 表 contact_data 没有名为的列 timestamp_: ,编译时:INSERT INTO 联系人数据(联系人号码, 持续时间,contact_id,timestamp_, number_type,contact_name, current_time,类型,续,日期) 值(?,?,?,?,?,?,?,?,?,?);
【问题讨论】:
【参考方案1】:我认为这是Java和SQLite之间绑定代码的错误。您可以尝试将“timestamp_”重命名为“time_stamp”进行测试吗?
【讨论】:
错误仍然存在 time_stamp。 PS:我只是将它命名为时间戳,虽然这是原因,但我将其命名为 timestamp_ 并且错误仍然存在。但这不是问题,因为第二个 sql 语句(声明表rated_contacts)创建此列,但不是为第一个表。以上是关于android.database.sqlite.SQLiteException:表contact_data没有名为timestamp_的列的主要内容,如果未能解决你的问题,请参考以下文章