无法查询 Android 中的数据库

Unable to query database in Android

我试图制作一个购物应用程序的购物车,我首先查询一个购物车元素,然后从购物车的 ID 中,列表元素通过查询另一个元素找到与产品相关的相应元数据 table 包含产品信息。我能够在显示 "menu" 的同时 成功查询产品列表 并尝试将相同的代码应用于购物车。然而它告诉我列“_id”不存在。我坚持了一段时间。

You can find the entire project on GitHub

这里是相关文件的重要部分

YourCart.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_your_cart);

    ContentValues values = new ContentValues();

    values.put(CartContract.CartEntry._ID, 2);
    values.put(CartContract.CartEntry.COLUMN_NAME_ORDERED_QUANTITY, 37);

    getContentResolver().insert(CartContract.CartEntry.CONTENT_URI, values);

    String[] projection = {

            CartContract.CartEntry._ID,
            CartContract.CartEntry.COLUMN_NAME_ORDERED_QUANTITY

    };

    //gets the entire cart
    cart = getContentResolver().query(CartContract.CartEntry.CONTENT_URI, projection, null, null, null);

    ListView cartList = findViewById(R.id.CartListView);
    cartList.setAdapter(new cartAdapter(YourCart.this, cart));

}

// Following is part of cartAdapter
@Override
    public void bindView(View view, Context context, Cursor cart) {


        prodName = view.findViewById(R.id.cartListElementProductNameTextView);
        prodPrice = view.findViewById(R.id.cartListElementProductPriceTextView);

        //Projection is just the name of the columns we would like to receive
        String[] projection = {

                ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_THUMBNAIL,
                ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_NAME,
                ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_PRICE

        };

        Integer ui = cart.getInt(cart.getColumnIndexOrThrow(CartContract.CartEntry._ID));

        String[] hoho = {ui.toString()};

        Cursor productCursor = getContentResolver().query(ProductListContract.ProductEntry.CONTENT_URI, projection, ProductListContract.ProductEntry._ID, hoho, null);

        prodName.setText(productCursor.getInt(productCursor.getColumnIndexOrThrow(ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_NAME)));

        ui = productCursor.getInt(productCursor.getColumnIndexOrThrow(ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_PRICE));
        prodPrice.setText(ui.toString());

        productCursor.close();

    }

我很确定在创建 table 时也会创建该列,从数据库助手

的摘录中可以看出
 public static final String SQL_CREATE_ENTRIES =
        "CREATE TABLE " + TABLE_NAME + " ( " +
                _ID + " INTEGER NON NULL, " +
                COLUMN_NAME_ORDERED_QUANTITY + " INTEGER)";

最后是崩溃日志。一旦启动 YourCart activity,应用程序就会崩溃

    03-16 09:50:30.987 11672-11672/com.example.tanmay.shoppingapp E/SQLiteLog: (1) table cart has no column named _id
03-16 09:50:30.991 11672-11672/com.example.tanmay.shoppingapp E/SQLiteDatabase: Error inserting quantity=37 _id=2
                                                                                android.database.sqlite.SQLiteException: table cart has no column named _id (code 1): , while compiling: INSERT INTO cart(quantity,_id) VALUES (?,?)
                                                                                    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                                    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
                                                                                    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
                                                                                    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                                                    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                                                                                    at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
                                                                                    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1472)
                                                                                    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1343)
                                                                                    at com.example.tanmay.shoppingapp.DataSet.DataProvider.insertCart(DataProvider.java:169)
                                                                                    at com.example.tanmay.shoppingapp.DataSet.DataProvider.insert(DataProvider.java:155)
                                                                                    at android.content.ContentProvider$Transport.insert(ContentProvider.java:264)
                                                                                    at android.content.ContentResolver.insert(ContentResolver.java:1279)
                                                                                    at com.example.tanmay.shoppingapp.YourCart.onCreate(YourCart.java:34)
                                                                                    at android.app.Activity.performCreate(Activity.java:6684)
                                                                                    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
                                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2652)
                                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2766)
                                                                                    at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
                                                                                    at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                    at android.os.Looper.loop(Looper.java:154)
                                                                                    at android.app.ActivityThread.main(ActivityThread.java:6236)
                                                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
03-16 09:50:30.991 11672-11672/com.example.tanmay.shoppingapp E/com.whatever.tag: Failed to insert row for content://com.example.tanmay.shoppingapp/cart
03-16 09:50:30.992 11672-11672/com.example.tanmay.shoppingapp E/SQLiteLog: (1) no such column: _id
03-16 09:50:30.994 11672-11672/com.example.tanmay.shoppingapp D/AndroidRuntime: Shutting down VM
03-16 09:50:30.996 11672-11672/com.example.tanmay.shoppingapp E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                Process: com.example.tanmay.shoppingapp, PID: 11672
                                                                                java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tanmay.shoppingapp/com.example.tanmay.shoppingapp.YourCart}: android.database.sqlite.SQLiteException: no such column: _id (code 1): , while compiling: SELECT _id, quantity FROM cart
                                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2699)
                                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2766)
                                                                                    at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
                                                                                    at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                    at android.os.Looper.loop(Looper.java:154)
                                                                                    at android.app.ActivityThread.main(ActivityThread.java:6236)
                                                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
                                                                                 Caused by: android.database.sqlite.SQLiteException: no such column: _id (code 1): , while compiling: SELECT _id, quantity FROM cart
                                                                                    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                                    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
                                                                                    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
                                                                                    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                                                    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                                                                                    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                                                    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                                                                                    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1318)
                                                                                    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1165)
                                                                                    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1036)
                                                                                    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1204)
                                                                                    at com.example.tanmay.shoppingapp.DataSet.DataProvider.query(DataProvider.java:92)
                                                                                    at android.content.ContentProvider.query(ContentProvider.java:1020)
                                                                                    at android.content.ContentProvider$Transport.query(ContentProvider.java:239)
                                                                                    at android.content.ContentResolver.query(ContentResolver.java:534)
                                                                                    at android.content.ContentResolver.query(ContentResolver.java:475)
                                                                                    at com.example.tanmay.shoppingapp.YourCart.onCreate(YourCart.java:44)
                                                                                    at android.app.Activity.performCreate(Activity.java:6684)
                                                                                    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
                                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2652)
                                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2766) 
                                                                                    at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507) 
                                                                                    at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                    at android.os.Looper.loop(Looper.java:154) 
                                                                                    at android.app.ActivityThread.main(ActivityThread.java:6236) 
                                                                                    at java.lang.reflect.Method.invoke(Native Method) 
                                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891) 
                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781) 

尝试用这个替换您的创建 SQL_CREATE_ENTRIES 语句,

 public static final String SQL_CREATE_ENTRIES =
    "CREATE TABLE " + TABLE_NAME + " ( " +
            _ID + " INTEGER NOT NULL, " +
            COLUMN_NAME_ORDERED_QUANTITY + " INTEGER)";

您的查询在 _ID 列中包含无效关键字,即 "NON"。

出于某种原因,table 不包含名为 _id 的列。但是,这不是因为 SQL,即使 SQL 可能不会按照您的意愿进行。

更具体地说,使用 INTEGER NON(而不是 NOT)NULL 将不会添加 NOT NULL 约束,它会给列一个 column_type of INTEGER NON,因为它包含 INT,所以等同于 INTEGER.

的 column-type(亲和力)

作为一个例子(这利用了 logDatabaseInfo )其中 SQL 作为 :-

CREATE TABLE cart (_ID INTEGER NON NULL, quantity INTEGER)

显示:-

D/SQLITE_CSU: DatabaseList Row 1 Name=main File=/data/data/soupd.so49313202updatefailed/databases/mydb
D/SQLITE_CSU: Database Version = 1
D/SQLITE_CSU: Table Name = android_metadata Created Using = CREATE TABLE android_metadata (locale TEXT)
D/SQLITE_CSU: Table = android_metadata ColumnName = locale ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
D/SQLITE_CSU: Table Name = cart Created Using = CREATE TABLE cart (_ID INTEGER NON NULL, quantity INTEGER)
D/SQLITE_CSU: Table = cart ColumnName = _ID ColumnType = INTEGER NON Default Value = null PRIMARY KEY SEQUENCE = 0
D/SQLITE_CSU: Table = cart ColumnName = quantity ColumnType = INTEGER Default Value = null PRIMARY KEY SEQUENCE = 0

Table = cart ColumnName = _ID ColumnType = INTEGER NON 默认值 = null 是相关信息。

SQL 应该是:-

CREATE TABLE cart (_ID INTEGER NOT NULL, quantity INTEGER)

  • Note normally _id/_ID is used for a column that holds a unique identifier that is automatically generated by SQLite, and thus typically you would have _ID INTEGER PRIMARY KEY for the column definition. Coding this and not providing a value for the _id will result in the unique identifier being generated by SQLite (typically 1,2,3,4.....).
  • Note I haven't shown this in the SQL below because you would need to look at inserting without the id.

可能真正的问题

真正的问题在别处,但很可能是由于没有调用 DatabaseHelper 的 onCreate 方法。由于数据库存在,它可能被调用过一次。所以最有可能的问题是 table 结构已更改但数据库尚未删除。

更具体地说,onCreate 方法仅在创建数据库时(自动)调用一次。

可能的修复

可能的解决方法是删除数据库,然后重新运行应用程序。 - 您可以通过删除应用程序的数据来删除数据库 - 或通过卸载应用程序。 - 我建议如上所示更改 SQL。