Android Studio SQLite错误:列不正确(“无此类列:_id”)

bf1o4zei  于 2023-10-23  发布在  SQLite
关注(0)|答案(2)|浏览(116)

我在一个Android应用程序中设置了一个SQLite数据库,但是为了专注于immeidate问题,我只会引用Users表。在DatabaseContract中,Users表定义为:

public final class DatabaseContract {
    private DatabaseContract() {}

    public static class Users implements BaseColumns {
        public static final String TABLE_NAME = "users";
        public static final String COLUMN_USER_ID = "_id";
        public static final String COLUMN_USER_NAME = "user_name";
        public static final String COLUMN_PASSWORD = "password";
        public static final String COLUMN_EMAIL = "email";
        public static final String COLUMN_DISPLAY_NAME = "display_name";
    }
    ...rest of tables in db
}

DatabaseHelper类中,这是Users表:

private static final String SQL_CREATE_USERS_TABLE =
            "CREATE TABLE " + DatabaseContract.Users.TABLE_NAME + " (" +
                    DatabaseContract.Users.COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    DatabaseContract.Users.COLUMN_USER_NAME + " TEXT NOT NULL, " +
                    DatabaseContract.Users.COLUMN_PASSWORD + " TEXT NOT NULL, " +
                    DatabaseContract.Users.COLUMN_EMAIL + " TEXT, " +
                    DatabaseContract.Users.COLUMN_DISPLAY_NAME + " TEXT)";

在我的AddUserActivity类中运行这个方法addUserToDatabase(String name, String email, String password, String displayName),它似乎可以工作,但是我希望从Users表中获取自动生成的'id',然后在这里检索'id':

// Check if the insertion was successful
        if (newRowId != -1) {
            // User was added successfully
            Toast.makeText(this, "User added successfully!", Toast.LENGTH_SHORT).show();

            // Get the user_id of the newly added user
            int user_id = getUserId(db, name);
      ...

下面是getUserId(db, name)方法:

private int getUserId(SQLiteDatabase db, String name) {
        int user_id = -1; // Default value if no user is found

        // Define the columns you want to retrieve
        String[] projection = {
                DatabaseContract.Users.COLUMN_USER_ID
        };

        // Define the selection based on the user name
        String selection = DatabaseContract.Users.COLUMN_USER_NAME + " = ?";
        String[] selectionArgs = { name };

        // Define the sort order (if needed)
        String sortOrder = null;

        Cursor cursor = db.query(
                DatabaseContract.Users.TABLE_NAME,
                projection,
                selection,
                selectionArgs,
                null,
                null,
                sortOrder
        );

        if (cursor.moveToFirst()) {
            // Get the user_id from the cursor
            int usersIdIndex = cursor.getColumnIndexOrThrow(DatabaseContract.Users.COLUMN_USER_ID);
            user_id = cursor.getInt(usersIdIndex);
        }

        // Close the cursor (don't close the database here)
        cursor.close();

        return user_id;
    }

然后我创建一个Intent,将此数据传递到WelcomeActivity页面:

...
            // Create an Intent to navigate to WelcomeActivity
            Intent intent = new Intent(AddUserActivity.this, WelcomeActivity.class);

            int testNumber = 777;
            // Pass user data and user_id as extras in the Intent
            intent.putExtra("USER_ID", user_id);//testNumber
            intent.putExtra("USER_NAME", name);
            intent.putExtra("USER_EMAIL", email);
            intent.putExtra("USER_DISPLAY_NAME", displayName);

            // Start the WelcomeActivity
            startActivity(intent);

            // Close this activity
            finish();

此时,程序崩溃并出现以下错误:

E/SQLiteLog: (1) no such column: _id in "SELECT _id FROM users WHERE user_name = ?"
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.enetapplications.songtracker, PID: 5937
    android.database.sqlite.SQLiteException: no such column: _id (code 1 SQLITE_ERROR[1]): , while compiling: SELECT _id FROM users WHERE user_name = ?
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1478)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:916)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:63)
        at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
        at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
        at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:2088)
        at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1935)
        at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1806)
        at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1974)
        at com.enetapplications.songtracker.AddUserActivity.getUserId(AddUserActivity.java:124)
        at com.enetapplications.songtracker.AddUserActivity.addUserToDatabase(AddUserActivity.java:84)
        at com.enetapplications.songtracker.AddUserActivity.access$400(AddUserActivity.java:20)
        at com.enetapplications.songtracker.AddUserActivity$1.onClick(AddUserActivity.java:58)
        at android.view.View.performClick(View.java:7792)
        at android.widget.TextView.performClick(TextView.java:16112)
        at android.view.View.performClickInternal(View.java:7769)
        at android.view.View.access$3800(View.java:910)
        at android.view.View$PerformClick.run(View.java:30218)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at android.app.ActivityThread.main(ActivityThread.java:8663)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

我是SQLite的新手,因此适应了SQLite -但对标准SQL/MySQL非常熟悉。我倾向于将Users表的键命名为user_id,但SQLite标准似乎将表的键保留为_id
提前感谢您的审查和评论!
最好的,布莱恩

brjng4g3

brjng4g31#

这是一个非常奇怪的问题
不,它不是,它应该是这样的。不像Activities等,onCreate经常被称为数据库是一个持久性实体,否则它将是无用的(至少对于它的预期目的)。无论设备或应用程序的状态如何,都需要保留存储在其中的数据(除非当用户选择不再需要数据时删除)。此外,当更新应用程序时,可能必须保留数据(这可能涉及或可能不涉及对数据库模式的更改)。
简单地说,onCreate方法反映了这样一个事实,即只有在创建数据库时才调用它。
如果需要更改,那么就是onUpdate(或很少使用的onDownGrade)发挥作用的时候。这两者都是由数据库版本驱动的,就像在构造一个扩展SQLiteOpenHelper的类时传递的那样。
我一直收到错误,无法撤消原始的数据库配置。
根据评论。SQLiteOpenHelper的 (因此也是一个扩展SQLiteOpenHelper的类)onCreate方法在数据库的生存期内只被调用一次。因此,对代码的任何更改(通常是在最初创建表的地方)将不会反映为代码不运行。

  • 参见https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)

如果在发布之前开发应用程序,并且数据库所持有的数据可能会丢失,那么所需的就是删除数据库。这可以通过卸载App来实现。由于没有数据库,onCreate将被调用。
如果应用程序已经发布,或者需要保留数据,则可以使用数据库版本和onUpdate方法从较低版本迁移数据库。

  • 请参阅https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper#onUpgrade(android. database. sqlite. SQLiteDatabase,%20int,%20int)

解决方案是更改数据库名称-只需添加“2”:private static final String DATABASE_NAME =“song_tracker2.db”;
这是因为您现在已经指定了另一个数据库作为要使用的数据库,因此onCreate方法已经被调用,并且模式与预期的一样。但是,原始数据库仍然存在,并浪费一些存储空间。

演示迁移

以下是如何使用onUpgrade方法来引入更改的工作演示(即使只是卸载应用程序就足够了,因为您很乐意使用另一个数据库)。
演示所做的是展示如何使用onUpgrade方法保留数据。它展示了一种基本的方法,几乎可以将任何更改应用于表。在本例中,将主键的列名从users_id更改为_id。
因此,请考虑以下DatabaseHelper类(显然您将拥有自己的类):

class DatabaseHelper extends SQLiteOpenHelper {

    private static final String SQL_CREATE_USERS_TABLE =
            "CREATE TABLE " + DatabaseContract.Users.TABLE_NAME + " (" +
                    DatabaseContract.Users.COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    DatabaseContract.Users.COLUMN_USER_NAME + " TEXT NOT NULL, " +
                    DatabaseContract.Users.COLUMN_PASSWORD + " TEXT NOT NULL, " +
                    DatabaseContract.Users.COLUMN_EMAIL + " TEXT, " +
                    DatabaseContract.Users.COLUMN_DISPLAY_NAME + " TEXT)";

    private static volatile DatabaseHelper instance;

    private DatabaseHelper(Context context) {
        super(context, DatabaseContract.DATABASE_NAME, null, DatabaseContract.DATABASE_VERSION);
    }

    public static DatabaseHelper getInstance(Context context) {
        if (instance == null) {
            instance = new DatabaseHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_USERS_TABLE);
        // .... other tables
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion <= 2) {migrateDBFromVersion1ToVersion2(db);}
    }

    private void migrateDBFromVersion1ToVersion2(SQLiteDatabase db) {
        final String ORIGINAL_PREFIX = "original_";
        db.beginTransaction();
        try {
            db.execSQL("DROP TABLE IF EXISTS " + ORIGINAL_PREFIX + DatabaseContract.Users.TABLE_NAME);
            db.execSQL(
                    "ALTER TABLE " + DatabaseContract.Users.TABLE_NAME +
                            " RENAME TO " + ORIGINAL_PREFIX + DatabaseContract.Users.TABLE_NAME
            );
            db.execSQL(SQL_CREATE_USERS_TABLE);
            db.execSQL("INSERT INTO " + DatabaseContract.Users.TABLE_NAME +
                    " SELECT * FROM " + ORIGINAL_PREFIX + DatabaseContract.Users.TABLE_NAME);
            db.execSQL("DROP TABLE IF EXISTS " + ORIGINAL_PREFIX + DatabaseContract.Users.TABLE_NAME);
            db.setTransactionSuccessful();
        } catch (SQLiteException e) {
            e.printStackTrace();
            //....
        }
        db.endTransaction();
    }

    public void logSchema() {
        Cursor csr = instance.getWritableDatabase().rawQuery("SELECT * FROM sqlite_master;", null);
        Log.i("DBVERSION","Database version is " + instance.getWritableDatabase().getVersion() +
                "; Path to database is " + instance.getWritableDatabase().getPath());
        DatabaseUtils.dumpCursor(csr);
        csr.close();
    }
}

上述重要因素包括:

  • onUpgrade方法中的编码,如果从小于版本2的版本升级到版本2,将调用migrateDBFromVersion1ToVersion2
  • migrateDBFromVersion1ToVersion2中遵循的基本过程是:
  • 删除将重命名为原始表的表(以防万一)
  • 重命名原始表
  • 使用新的/更改的SQL创建替换表(这也应该始终反映在onCreate方法中,以便新的应用程序安装具有相同的模式)
  • 用来自表格的原始/先前版本的数据填充表格(即,重命名的表)
  • 删除重命名的原始表(为运行演示而注解掉)
  • 所有上述内容都在一个事务中进行,只有在没有SQLite异常的情况下才提交。如果出现SQLite异常,则事务将回滚,因此不会应用任何更改。
  • logSchema方法类似于getTableMetaData方法。

然后,DatabaseContract类作为驱动程序发挥作用,它被更改为包括数据库名称和版本,如下所示:-

public final class DatabaseContract {
    private DatabaseContract() {}

    public static final String DATABASE_NAME = "song_tracker.db";
    public static final int DATABASE_VERSION = 1;

    public static class Users implements BaseColumns {
        public static final String TABLE_NAME = "users";
        //public static final String COLUMN_USER_ID = "_id"; /* Version 2 */
        public static final String COLUMN_USER_ID = "users_id"; /* Version 1 */
        public static final String COLUMN_USER_NAME = "user_name";
        public static final String COLUMN_PASSWORD = "password";
        public static final String COLUMN_EMAIL = "email";
        public static final String COLUMN_DISPLAY_NAME = "display_name";
    }
    // ...rest of tables in db
}

显然,在一个活动中需要做一些事情,所以:

public class MainActivity extends AppCompatActivity {

    DatabaseHelper dbHelper;

    @SuppressLint("Range")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbHelper = DatabaseHelper.getInstance(this);
        if (DatabaseContract.DATABASE_VERSION == 1) {
            SQLiteDatabase db = dbHelper.getReadableDatabase();
            ContentValues cv = new ContentValues();
            cv.put(DatabaseContract.Users.COLUMN_DISPLAY_NAME,"Fred");
            cv.put(DatabaseContract.Users.COLUMN_EMAIL,"fred.bloggs.nomail.moc");
            cv.put(DatabaseContract.Users.COLUMN_PASSWORD,"0987654321");
            cv.put(DatabaseContract.Users.COLUMN_USER_NAME,"USER00001");
            db.insert(DatabaseContract.Users.TABLE_NAME,null,cv);
        }
        dbHelper.logSchema();
        Cursor csr = dbHelper.getWritableDatabase().query(
                DatabaseContract.Users.TABLE_NAME,
                null,null,null,null,null,null
        );
        while (csr.moveToNext()) {
            Log.i(
                    "USERDATA",
                    "User Name is " + csr.getString(csr.getColumnIndex(DatabaseContract.Users.COLUMN_USER_NAME))
                    + " Email is " + csr.getString(csr.getColumnIndex(DatabaseContract.Users.COLUMN_EMAIL))
                    // ....
            );
        }
        csr.close();
    }
}

因此,这将:

  • 获取DatabaseHelper的示例
  • 如果数据库版本(根据代码)为1,则插入一行
  • 注意,在此阶段,实际数据库版本可能与编码版本不同。数据库的实际版本存储在数据库文件的标头中。SQLiteOpenHelper在打开数据库时保留版本。如果代码和实际版本之间存在差异,则将调用onUpgrade或onDowngrade。
  • logSchema函数将模式输出到日志。
  • 从用户表中提取数据并将其写入日志。
    结果/测试1 -应用程序在版本1的新鲜安装

日志包括:

2023-09-14 07:53:24.666 I/DBVERSION: Database version is 1; Path to database is /data/user/0/a.a.so77093284javasqlitemigration/databases/song_tracker.db
2023-09-14 07:53:24.666 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@98fd0f5
2023-09-14 07:53:24.667 I/System.out: 0 {
2023-09-14 07:53:24.667 I/System.out:    type=table
2023-09-14 07:53:24.667 I/System.out:    name=android_metadata
2023-09-14 07:53:24.667 I/System.out:    tbl_name=android_metadata
2023-09-14 07:53:24.667 I/System.out:    rootpage=3
2023-09-14 07:53:24.667 I/System.out:    sql=CREATE TABLE android_metadata (locale TEXT)
2023-09-14 07:53:24.667 I/System.out: }
2023-09-14 07:53:24.667 I/System.out: 1 {
2023-09-14 07:53:24.667 I/System.out:    type=table
2023-09-14 07:53:24.667 I/System.out:    name=users
2023-09-14 07:53:24.668 I/System.out:    tbl_name=users
2023-09-14 07:53:24.668 I/System.out:    rootpage=4
2023-09-14 07:53:24.668 I/System.out:    sql=CREATE TABLE users (users_id INTEGER PRIMARY KEY AUTOINCREMENT, user_name TEXT NOT NULL, password TEXT NOT NULL, email TEXT, display_name TEXT)
2023-09-14 07:53:24.668 I/System.out: }
2023-09-14 07:53:24.668 I/System.out: 2 {
2023-09-14 07:53:24.668 I/System.out:    type=table
2023-09-14 07:53:24.668 I/System.out:    name=sqlite_sequence
2023-09-14 07:53:24.668 I/System.out:    tbl_name=sqlite_sequence
2023-09-14 07:53:24.668 I/System.out:    rootpage=5
2023-09-14 07:53:24.668 I/System.out:    sql=CREATE TABLE sqlite_sequence(name,seq)
2023-09-14 07:53:24.668 I/System.out: }
2023-09-14 07:53:24.668 I/System.out: <<<<<
2023-09-14 07:53:24.669 I/USERDATA: User Name is USER00001 Email is fred.bloggs.nomail.moc

因此,用户表具有

  • users_id、user_name、password、email和display_name。按照原始版本。
  • USER 00001的1行数据
    结果/测试2-应用程序刚刚使用更改的代码重新启动

对于此测试,更改了3行代码:

  • public static final int DATABASE_VERSION = 2;(为1

  • public static final String COLUMN_USER_ID = "_id"; /* Version 2 */(已注解掉)

  • //public static final String COLUMN_USER_ID = "users_id"; /* Version 1 */(未注解)

日志现在包括:

2023-09-14 08:03:06.896 I/DBVERSION: Database version is 2; Path to database is /data/user/0/a.a.so77093284javasqlitemigration/databases/song_tracker.db
2023-09-14 08:03:06.896 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@98fd0f5
2023-09-14 08:03:06.897 I/System.out: 0 {
2023-09-14 08:03:06.897 I/System.out:    type=table
2023-09-14 08:03:06.897 I/System.out:    name=android_metadata
2023-09-14 08:03:06.897 I/System.out:    tbl_name=android_metadata
2023-09-14 08:03:06.897 I/System.out:    rootpage=3
2023-09-14 08:03:06.897 I/System.out:    sql=CREATE TABLE android_metadata (locale TEXT)
2023-09-14 08:03:06.897 I/System.out: }
2023-09-14 08:03:06.897 I/System.out: 1 {
2023-09-14 08:03:06.897 I/System.out:    type=table
2023-09-14 08:03:06.897 I/System.out:    name=original_users
2023-09-14 08:03:06.897 I/System.out:    tbl_name=original_users
2023-09-14 08:03:06.897 I/System.out:    rootpage=4
2023-09-14 08:03:06.898 I/System.out:    sql=CREATE TABLE "original_users" (users_id INTEGER PRIMARY KEY AUTOINCREMENT, user_name TEXT NOT NULL, password TEXT NOT NULL, email TEXT, display_name TEXT)
2023-09-14 08:03:06.898 I/System.out: }
2023-09-14 08:03:06.898 I/System.out: 2 {
2023-09-14 08:03:06.898 I/System.out:    type=table
2023-09-14 08:03:06.898 I/System.out:    name=sqlite_sequence
2023-09-14 08:03:06.898 I/System.out:    tbl_name=sqlite_sequence
2023-09-14 08:03:06.898 I/System.out:    rootpage=5
2023-09-14 08:03:06.898 I/System.out:    sql=CREATE TABLE sqlite_sequence(name,seq)
2023-09-14 08:03:06.898 I/System.out: }
2023-09-14 08:03:06.898 I/System.out: 3 {
2023-09-14 08:03:06.898 I/System.out:    type=table
2023-09-14 08:03:06.898 I/System.out:    name=users
2023-09-14 08:03:06.899 I/System.out:    tbl_name=users
2023-09-14 08:03:06.899 I/System.out:    rootpage=6
2023-09-14 08:03:06.899 I/System.out:    sql=CREATE TABLE users (_id INTEGER PRIMARY KEY AUTOINCREMENT, user_name TEXT NOT NULL, password TEXT NOT NULL, email TEXT, display_name TEXT)
2023-09-14 08:03:06.899 I/System.out: }
2023-09-14 08:03:06.899 I/System.out: <<<<<
2023-09-14 08:03:06.900 I/USERDATA: User Name is USER00001 Email is fred.bloggs.nomail.moc

:-

  • 数据库版本(从数据库中提取的实际版本)已增加到2。
  • 用户表的列现在是”-
    *_id,根据变更
  • 用户名,
  • 请输入密码,
  • 电子邮件和
  • 显示名称(_N)
  • 由于最后一个DROP TABLE original_users的执行被注解掉了,现在不需要的original_users表仍然存在,它有users_id列,而不是新的**_id**列。
    结果/测试3全新安装-版本2代码

该应用程序被禁用,然后运行日志包括:-

2023-09-14 08:12:01.230 I/DBVERSION: Database version is 2; Path to database is /data/user/0/a.a.so77093284javasqlitemigration/databases/song_tracker.db
2023-09-14 08:12:01.230 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@98fd0f5
2023-09-14 08:12:01.230 I/System.out: 0 {
2023-09-14 08:12:01.230 I/System.out:    type=table
2023-09-14 08:12:01.230 I/System.out:    name=android_metadata
2023-09-14 08:12:01.230 I/System.out:    tbl_name=android_metadata
2023-09-14 08:12:01.230 I/System.out:    rootpage=3
2023-09-14 08:12:01.231 I/System.out:    sql=CREATE TABLE android_metadata (locale TEXT)
2023-09-14 08:12:01.231 I/System.out: }
2023-09-14 08:12:01.231 I/System.out: 1 {
2023-09-14 08:12:01.231 I/System.out:    type=table
2023-09-14 08:12:01.231 I/System.out:    name=users
2023-09-14 08:12:01.231 I/System.out:    tbl_name=users
2023-09-14 08:12:01.231 I/System.out:    rootpage=4
2023-09-14 08:12:01.231 I/System.out:    sql=CREATE TABLE users (_id INTEGER PRIMARY KEY AUTOINCREMENT, user_name TEXT NOT NULL, password TEXT NOT NULL, email TEXT, display_name TEXT)
2023-09-14 08:12:01.231 I/System.out: }
2023-09-14 08:12:01.231 I/System.out: 2 {
2023-09-14 08:12:01.231 I/System.out:    type=table
2023-09-14 08:12:01.231 I/System.out:    name=sqlite_sequence
2023-09-14 08:12:01.231 I/System.out:    tbl_name=sqlite_sequence
2023-09-14 08:12:01.231 I/System.out:    rootpage=5
2023-09-14 08:12:01.231 I/System.out:    sql=CREATE TABLE sqlite_sequence(name,seq)
2023-09-14 08:12:01.231 I/System.out: }
2023-09-14 08:12:01.231 I/System.out: <<<<<
  • 列为**_id**,
  • 没有休眠的original_users表,并且
  • 没有数据(因为应用程序仅在编码版本为1时添加数据)
jrcvhitl

jrcvhitl2#

这是一个非常奇怪的问题-在应用程序开发的早期,在我的Users表中,我的键是users_id,但后来更改了它(在DatabaseHelperDatabaseContract中更改为user_id)。最后,我能够“看到”db Meta数据,意识到所有这些修改都没有做任何事情:

public void getTableMetadata(String tableName) {
        Log.d("SplashActivityZ", "IN: getTableMetadata(String tableName) - in DatabaseHelper.java, tableName=" + tableName + ")");
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);

        if (cursor != null) {
            try {
                if (cursor.moveToFirst()) {
                    do {
                        String columnName = cursor.getString(cursor.getColumnIndex("name"));
                        String columnType = cursor.getString(cursor.getColumnIndex("type"));

                        // Log the metadata for each column
                        Log.d("SplashActivityZ", "Column Name: " + columnName);
                        Log.d("SplashActivityZ", "Column Type: " + columnType);
                    } while (cursor.moveToNext());
                }
            } finally {
                cursor.close();
            }
        }
    }

输出一致:D Column Name: users_id
其他尝试包括更改版本:private static final int DATABASE_VERSION = 3;也没做什么。

解决方案是更改数据库名称-仅添加“2”:private static final String DATABASE_NAME = "song_tracker2.db";

解决了问题。

相关问题