安卓. SQLite 异常:没有名为 _id 的列

5

我遇到了一些问题,想要从我的数据库中获取信息,并在ListView中显示它。

这是我想要显示行的ListActivity:

public class Prueba extends ListActivity{

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.i_prueba);

        DataBaseAccess db = new DataBaseAccess(this);
        db.open();

        Cursor result = db.getAllContact();
        startManagingCursor(result);


        // the desired columns to be bound
        String[] columns = new String[] {"_id", "nombre", "telefono", "mail"};
        // the XML defined views which the data will be bound to
        int[] to = new int[] { R.id.textid, R.id.textNombre, R.id.textTelefono, R.id.textMail };

        SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.i_listadb, result, columns, to);


        this.setListAdapter(mAdapter);

    }

DB类。这里是getAllContact方法,我遇到了错误:

public class DataBaseAccess {

public static final String NOMBRE = "nombre";
public static final String TELEFONO = "telefono";
public static final String MAIL = "mail";
public static final String ID = "_id";


    public DataBaseAccess(Context context) {
        this.androidContext = context;
//DataBaseHelper is another class where the Database is created. In the "onCreate" //method of that class is where i make the CREATE TABLE and add some values to that //table.
        dbHelper = new DataBaseHelper(androidContext);  
    }



    public void open() throws SQLException {
        db = dbHelper.getWritableDatabase();
        }



[...MORE METHODS...]

    public Cursor getAllContact(){
        String[] columnas = new String[] {ID, NOMBRE, TELEFONO, MAIL};
        Cursor mCursor = dbHelper.query("t_contactos", columnas, null, null, null, null, null);
    if (mCursor != null){
        mCursor.moveToFirst();
    }
    return mCursor;
}

以下是来自LogCat的错误信息:

}

E/AndroidRuntime(  636): Uncaught handler: thread main exiting due to uncaught exception

E/AndroidRuntime(  636): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pfc.android/com.pfc.android.Prueba}: android.database.sqlite.SQLiteException: no such column: _id: , while compiling: SELECT _id, nombre, telefono, mail FROM t_contactos

E/AndroidRuntime(  636):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)

E/AndroidRuntime(  636):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)

E/AndroidRuntime(  636):    at android.app.ActivityThread.access$2100(ActivityThread.java:116)

E/AndroidRuntime(  636):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)

E/AndroidRuntime(  636):    at android.os.Handler.dispatchMessage(Handler.java:99)

E/AndroidRuntime(  636):    at android.os.Looper.loop(Looper.java:123)

E/AndroidRuntime(  636):    at android.app.ActivityThread.main(ActivityThread.java:4203)

E/AndroidRuntime(  636):    at java.lang.reflect.Method.invokeNative(Native Method)

E/AndroidRuntime(  636):    at java.lang.reflect.Method.invoke(Method.java:521)

E/AndroidRuntime(  636):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)

E/AndroidRuntime(  636):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)

E/AndroidRuntime(  636):    at dalvik.system.NativeStart.main(Native Method)

E/AndroidRuntime(  636): Caused by: android.database.sqlite.SQLiteException: no such column: _id: , while compiling: SELECT _id, nombre, telefono, mail FROM t_contactos

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteProgram.native_compile(Native Method)

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteProgram.compile(SQLiteProgram.java:110)

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49)

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:49)

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1118)

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1006)

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:964)

E/AndroidRuntime(  636):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1041)

E/AndroidRuntime(  636):    at com.pfc.android.DataBaseAccess.getAllContact(DataBaseAccess.java:97)

E/AndroidRuntime(  636):    at com.pfc.android.Prueba.onCreate(Prueba.java:21)

E/AndroidRuntime(  636):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)

E/AndroidRuntime(  636):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)

E/AndroidRuntime(  636):    ... 11 more

所以,有人能帮助解决这个问题吗?提前感谢您!
6个回答

7
如果您创建了一个带有字段'a'、'b'和'c'的数据库,并在此基础上使用了该数据库,如果您添加了新字段(例如'd'),则需要在手机上重新创建数据库(只需删除原来的数据库)。

6

1
这是我的代码中的CREATE TABLE语句:“create table t_contactos (_id integer primary key autoincrement, nombre varchar not null, telefono varchar not null, mail varchar not null);”但是当我使用SqliteBrowser进行检查时,显示的列名只有“id”。你有什么想法吗? - Kitinz
尝试手动更正为_id,可能是在创建方法中出现了一些错误,不确定。 - Mathias Conradt
你的意思是重新在SQLiteBrowser中编写并将文件返回到手机,对吧?我会试一下。不管怎样,我发现了一些奇怪的东西。我在“onCreate”方法中有一些跟踪,其中我创建数据库并填充它,但我没有在任何地方看到这些跟踪,所以为了确保...当我创建一个类的新对象,在执行构造方法之后,它会执行onCreate吗? - Kitinz
是的,将文件推送回手机就是我想说的意思。OnCreate:这只对活动(Activities)自动调用,而不是一般的对象(简单的Java bean)。 - Mathias Conradt

4
尝试使用rowid而不是_id,这对我很有效。

在Python中对我有用。 - jigglypuff

1

没错,你应该在查询之前创建数据库表。

这里是一个例子:

 private static final String DATABASE_CREATE_DRIVERS =
        "create table " + DATABASE_TABLE_DRIVERS + "(" + KEY_ROWID +" integer primary key autoincrement, "
        + KEY_DRIVERID + " text not null,"
        + KEY_FIRST_NAME + " text not null,"
        + KEY_LAST_NAME + " text not null,"
        + KEY_SPEED_LIMIT + " int not null,"
        + KEY_TIMESTAMP + " int"
        + ");";

然后在这里查询:

 public Cursor fetchAllDrivers(){
     Cursor mCursor =
         mDb.query(true, DATABASE_TABLE_DRIVERS, new String[] {
                 KEY_ROWID, 
                 KEY_DRIVERID,
                 KEY_FIRST_NAME,
                 KEY_LAST_NAME,
                 KEY_SPEED_LIMIT,
                 KEY_TIMESTAMP},"", null,null, null, null, null);
     if (mCursor != null) {
         mCursor.moveToFirst();
     }
     return mCursor;
 }

同时看起来你缺少了第六个参数,用于查询什么。请看我在方法参数字符串中放置的 ""。


0

这里有两种可能性:

  1. 这个问题可能是由于损坏的SQLite模式引起的。

你的问题不是关于SQL语句的问题,但很多开发者会认为你的问题与SQL语句有关。

这种情况可以检查数据库文件中是否有损坏的数据。虽然你不能通过字段名使用选择字段和SQL where子句。

因此,在你的Android代码中不能使用数据库文件。

确切的解决方案是,我建议逐步重新创建SQLite DB文件。

在使用SQLite修改工具(SQLite Manager、Browser、其他数据库管理工具)之前,你必须备份。

  1. 这个问题是由于你的持久化数据引起的。

如果你在运行时使用相同的文件名来加载资产或原始数据,并且使用了修改后的数据,

你可以尝试卸载之前安装的应用程序以进行刷新。


-2

我把我的数据库名称改成了全小写,这对我起作用了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接