当我执行readNumber()方法时,我收到一条错误,说“没有列存在”,“CREATE”查询似乎是正确的

时间:2018-04-07 01:19:51

标签: android sqlite sqliteopenhelper

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DbHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "NumberDB";
    private static final int DATABASE_VERSION = 1;
    private static final String CREATE = "create table "+DBcontract.TABLE_NAME+ "(id integer primary key,"+DBcontract.INCOMING_NUMBER+" text);";
    private static final String DROP_TABLE = "drop table if exists "+DBcontract.TABLE_NAME;
    public DbHelper(Context context){
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(CREATE);
    }
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        sqLiteDatabase.execSQL(DROP_TABLE);
        onCreate(sqLiteDatabase);
    }
    public void saveNumber(String number,SQLiteDatabase sqLiteDatabase){
        ContentValues contentValues = new ContentValues();
        contentValues.put(DBcontract.INCOMING_NUMBER,number);
        sqLiteDatabase.insert(DBcontract.TABLE_NAME,null,contentValues);
    }
    public Cursor readNumber(SQLiteDatabase database){
        String[] projections = {"id",DBcontract.INCOMING_NUMBER};
        // Cursor c = sqLiteDatabase.rawQuery("SELECT * FROM IncomingNumber",null);
        // Log.i("Incoming number", String.valueOf(c));
        // Log.i("database name",sqLiteDatabase.toString());
        return( database.query(DBcontract.TABLE_NAME,  projections,null,null,null,null,null));
    }
}

在上面的代码中,我创建了一个String值和一个构造函数来创建数据库,并再次覆盖该方法以创建表。

这给了我readNumber method

的错误
  

“找不到列:incoming_number。

     

DBCONTRACT.TABLE_NAME =“incomingInfo”

     

DBCONTRACT.INCOMING_NUMBER =“incoming_number”。

1 个答案:

答案 0 :(得分:0)

我认为您的问题是您已经更改了表结构或更正了错误,因此在尝试运行实际上已调到onCreate方法阶段的App后,更改了表创建SQL。

我可以非常肯定上面是这种情况,因为我复制了你的 DbHelper 类,创建了一个 DBcontract 类,创建了一个名为的常见问题解答Are there any methods that assist with resolving common SQLite issues? 复制代码。

然后我按照以下方式从一个Activity中调用它: -

public class MainActivity extends AppCompatActivity {

    SO49702870DbHelper mDBHlper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHlper = new SO49702870DbHelper(this);

        //Test
        //    Display Database Information
        CommonSQLiteUtilities.logDatabaseInfo(mDBHlper.getWritableDatabase());
        // Get A cursor
        Cursor csr = mDBHlper.readNumber(mDBHlper.getWritableDatabase());
        CommonSQLiteUtilities.logCursorColumns(csr);
    }
}

不需要修改您的代码,输出完全符合预期,即按照: -

04-07 05:56:15.136 1301-1301/? D/SQLITE_CSU: DatabaseList Row 1 Name=main File=/data/data/soanswers.soanswers/databases/NumberDB
    Database Version = 1
    Table Name = android_metadata Created Using = CREATE TABLE android_metadata (locale TEXT)
    Table = android_metadata ColumnName = locale ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
    Table Name = incomingInfo Created Using = CREATE TABLE incomingInfo(id integer primary key,incoming_number text)
    Table = incomingInfo ColumnName = id ColumnType = integer Default Value = null PRIMARY KEY SEQUENCE = 1
    Table = incomingInfo ColumnName = incoming_number ColumnType = text Default Value = null PRIMARY KEY SEQUENCE = 0
    logCursorColumns invoked. Cursor has the following 2 columns.
04-07 05:56:15.140 1301-1301/? D/SQLITE_CSU: Column Name 1 is id
    Column Name 2 is incoming_number

即。有两个表: -

  1. android_metadata
    • 由数据库助手创建并存储语言环境。
  2. incomingInfo
    • 即。你的桌子
    • 它是使用CREATE TABLE incomingInfo(id integer primary key,incoming_number text)
    • 创建的
    • 它有两个已定义的列 id incoming_number
  3. 根本原因

    一个非常常见的误解是,onCreate方法在每次实例化Database Helper(SQLiteOpenHelper的子类)时运行。

    仅当数据库不存在时才调用onCreate方法。因此,如果数据库存在,则对onCreate方法中所执行的操作所做的任何更改都不会被操作。

    在创建数据库之后调用onCreate方法时,任何失败,例如创建表的SQL错误不会删除数据库,因此不会应用对SQL的更正。

    修复

    只要不需要保留数据(如果有),就可以通过三种方式调用onCreate: -

    1. 删除应用程序的数据并重新运行应用程序。
    2. 卸载应用程序并重新运行应用程序。
    3. 如果onUpgrade方法删除了表并调用onCreate方法(你的方法),则可以增加传递给SQLiteOpenHelper构造函数的数据库版本号,并重新运行App 。
      • 您的onUpgrade方法符合条件,因此您可以将private static final int DATABASE_VERSION = 1;更改为private static final int DATABASE_VERSION = 2;