我正在尝试在真实设备上调试我的应用程序但是我收到此错误:
错误/ AndroidRuntime(981):引起: java.lang.IllegalArgumentException异常: 列'_id'不存在
当我在模拟器上测试时,错误不会出现。错误在以下代码的最后一行中给出:
adapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String[] {
DataHandlerDB.CONTACT_NAME_COL,
DataHandlerDB.CONTACT_NUMBER_COL,
DataHandlerDB.CONTACT_DURATION_COL,
DataHandlerDB.CONTACT_DATE_COL }, new int[] {
R.id.contact_name, R.id.phone_number, R.id.duration, R.id.date });
这是我的活动:
public class MyActivity extends Activity {
private static final String LOG_TAG = "MyActivity";
private ListView listview;
private SimpleCursorAdapter adapter;
private DataHandlerDB handler;
private SQLiteDatabase db;
private OpenHelper helper;
private Cursor c;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
helper = new OpenHelper(this);
db = helper.getWritableDatabase();
helper.onCreate(db);
setBasicContent();
c.close();
}
@Override
public void onDestroy(){
super.onDestroy();
DataHandlerDB.makeTheSelection(this).close();
db.close();
helper.close();
}
@Override
public void onPause(){
super.onPause();
DataHandlerDB.makeTheSelection(this).close();
db.close();
helper.close();
}
@Override
public void onStop(){
super.onStop();
DataHandlerDB.makeTheSelection(this).close();
db.close();
helper.close();
}
@Override
protected void onResume(){
super.onResume();
setBasicContent();
}
public void setBasicContent() {
listview = (ListView) findViewById(R.id.list_view);
Log.i(LOG_TAG, "listview " + listview);
c = DataHandlerDB.makeTheSelection(this);
c.moveToFirst();
if(db.isOpen())
Log.i(LOG_TAG, "db is opened");
Log.i(LOG_TAG, "cursor: " + c.getCount());
startManagingCursor(c);
adapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String[] {
DataHandlerDB.CONTACT_NAME_COL,
DataHandlerDB.CONTACT_NUMBER_COL,
DataHandlerDB.CONTACT_DURATION_COL,
DataHandlerDB.CONTACT_DATE_COL }, new int[] {
R.id.contact_name, R.id.phone_number, R.id.duration, R.id.date });
Log.i(LOG_TAG, "before setAdapter");
Toast.makeText(this, "Before setAdapter", Toast.LENGTH_SHORT).show();
listview.setAdapter(adapter);
db.close();
if(db.isOpen()){
Log.i(LOG_TAG, "db is opened.");
}
if(!c.isClosed()){
Log.i(LOG_TAG, "cursor is opened");
}
}
}
查询并返回Cursor
的函数位于类DataHandlerDB
中:
public class DataHandlerDB {
private static final String DATABASE_NAME = "calls.db";
private static final int DATABASE_VERSION = 1;
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 Cursor makeTheSelection(Context ctx) {
OpenHelper helper = new OpenHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.query(TABLE_NAME_2, null, null, null, null, null,
"duration desc");
cursor.moveToFirst();
db.close();
return cursor;
}
// class OpenHelper
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) {
Log.i(LOG_TAG, "entrou no onCreate");
String[] sql = mContext.getString(
R.string.MyAppDatabase_OnCreate).split("\n");
db.beginTransaction();
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);
}
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("MyDB Database",
"Upgrading database, this will drop tables and recreate.");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db);
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
}
}
}
以下是带有SQL命令的XML文件:
<string name="MyAppDatabase_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, current_time TIME, cont INTEGER, type VARCHAR, month VARCHAR(50), day VARCHAR(50), year VARCHAR(50));"
</string>
我认为应用程序在首次启动时不会创建数据库。我这么认为是因为它可以找到列_id
,但它在XML代码中明确写入,以使用_id
列创建它。我也认为,因为我已经在SELECT
方法中明确写了列,包括_id
。我是这样做的:
Cursor cursor = db.query(TABLE_NAME_2,
new String[]{
"_id",
"contact_id",
"contact_name",
"number_type",
"contact_number",
"duration",
"duration_sum",
"date",
"current_time",
"cont", "type",
"month",
"day",
"year"}, null, null, null, null,
"duration desc");
在这种情况下,我收到的错误几乎相同:
引起: android.database.sqlite.SQLiteException: 没有这样的列:_id :,而 编译:SELECT _id,contact_id, contact_name,number_type, contact_number,期限, duration_sum,date,current_time, 续,类型,月,日,年FROM contact_data ORDER BY duration desc
我已经记录了数据库的第一列,如下所示:
Log.i(LOG_TAG, "Cursor(0)" + cursor.getColumnName(0));
它打印了id
,而不是_id
。如您所见,声明中写有_id
。关于如何解决这个问题的任何建议?
答案 0 :(得分:41)
您正在尝试使用需要一个名为_id的列的游标。它就像编辑表创建语句和添加名为_id的列一样简单。
它的声明看起来像这样:
_id INTEGER PRIMARY KEY AUTOINCREMENT
添加此项,然后您就可以使用它了。我认为这是使用SimpleCursorAdapter所必需的。
<强>更新强>
"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, current_time TIME, cont INTEGER, type VARCHAR, month VARCHAR(50), day VARCHAR(50), year VARCHAR(50));"
解决方案:在左括号'('和_id
之间添加一个空格答案 1 :(得分:12)
我遇到过类似的问题,因为我没有将 _id 列添加到投影参数中,因此添加 _id 对查询的projection参数是解决方案。 (由@nobugs评论)
示例:
String[] projections = {"_id", "name", "age"};
Cursor cursor = db.query(domainClass.getSimpleName(), projections,
null, null, null, null, null);
答案 2 :(得分:2)
首先卸载应用程序,然后执行以下步骤:
答案 3 :(得分:0)
CursorAdapter始终要求存在public dbadmin()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
ConnectionStringSettings conSettings = ConfigurationManager.ConnectionStrings["shopmanagerConnectionString1"];
MySqlConnection con = new MySqlConnection(conSettings.ToString());
con.Open();
MessageBox.Show("Connection ok");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
列。因此,在用于创建游标的投影列表中,您需要添加_id
列。
答案 4 :(得分:0)
我做到了,解决了我的问题。
之前
SELECT id
之后
SELECT id as _id