简体   繁体   English

SQLite将一列的值存储为-1,但其他列也可以

[英]SQLite stores value as -1 for one column, but other columns are fine

In my application recently I've added new column SUB_CATEGORY_ID to my existing table transactions . 最近,在我的应用程序中,我向现有的表事务中添加了新列SUB_CATEGORY_ID After I insert record with sub_category_id value as any integer, when I queried the table and checked it returns value as -1 for sub_category_id rest of the columns are fine. 在我插入带有sub_category_id值为任何整数的值的记录后,当我查询表并检查它为sub_category_id返回值时为-1,其余的列都可以。 I checked value for sub_category_id before inserting it is not null and having integer values like 1,2,... But still it is saving the value as -1. 我在插入sub_category_id之前检查了它的值,该值不为null,并且具有1,2,...之类的整数。

Any suggestions. 有什么建议么。 Please find my code below. 请在下面找到我的代码。

Code to add Transaction: 添加交易的代码:

public int addTransaction(int categoryId, int subCategoryId, int accountId, double amount,
                          String notes, String trxType, String subTrxType, int sourceTrxId) {

    Log.d("addTransaction", "before addTransaction "+subCategoryId);
    int flag=0;

    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(CATEGORY_ID_COL, categoryId);
    contentValues.put(ACCOUNT_ID_COL, accountId);
    contentValues.put(AMOUNT_COL, amount);
    contentValues.put(DUE_DATE_COL, getDateTime());
    contentValues.put(CREATION_DATE, getDateTime());
    contentValues.put(NOTES_COL, notes);
    contentValues.put(TRANSACTION_TYPE_COL, trxType);
    contentValues.put(TRANSACTION_SUB_TYPE_COL, subTrxType);
    contentValues.put(SOURCE_TRX_ID_COL, sourceTrxId);
    contentValues.put(SUB_CATEGORY_ID_COL, subCategoryId);
    db.insert(TRANSACTIONS_TABLE_NAME, null, contentValues);
    flag=1;
    return flag;
}

Code to query transaction records returns -1 for sub_category_id column: 查询事务记录的代码为sub_category_id列返回-1:

    String selectQuery1 = "SELECT TRX."+CATEGORY_ID_COL+", TRX."+SUB_CATEGORY_ID_COL+" from "+TRANSACTIONS_TABLE_NAME
            +" AS TRX ORDER BY DATETIME(TRX."+CREATION_DATE+") DESC LIMIT 50";
Cursor c1 = db.rawQuery(selectQuery1, null);
    if(c1.moveToFirst()){
        do{
            Log.d("fetchAllTrx", " CetgId="+c1.getLong(0)+" 
subcatgid="+c1.getLong(1));
        }while (c1.moveToNext());
    }
    c1.close();

A trap that many fall into at first, is assuming that the onCreate method runs every time and that changing the schema (adding/removing table or columns) can be implemented by just changing the SQL used to create the tables. 最初,很多人会陷入一个陷阱,即假设onCreate方法每次都运行,并且更改模式(添加/删除表或列)可以通过仅更改用于创建表的SQL来实现。

The onCreate method only runs automatically when the database is created. onCreate方法仅在创建数据库时自动运行。 So such changes will not normally be made. 因此,通常不会进行此类更改。

The easiest way to implement such schema changes is to either delete the App's data or uninstall the app. 实现此类架构更改的最简单方法是删除应用程序的数据或卸载应用程序。 A third, simple way, if the onUpgrade method has been written to drop the tables and then call the onCreate method , is to cause the onUpgrade method to run by increasing the database version number. 第三种简单的方法是, 如果已编写onUpgrade方法以删除表,然后调用onCreate方法 ,则可以通过增加数据库版本号来使onUpgrade方法运行。

Note that all three of the above methods will result in the loss of data. 请注意,上述所有三种方法都将导致数据丢失。 The first two delete the database causing it to be recreated. 前两个删除导致重新创建数据库的数据库。 The database itself will not be deleted with the third, rather the specified tables are dropped (delete) and then recreated. 数据库本身不会被第三个删除,而是删除(删除)指定的表然后重新创建。

If loss of existing data would be an issue, then you can use the onUpgrade method to implement changes that preserve the data. 如果丢失现有数据是一个问题,则可以使用onUpgrade方法来实现保留数据的更改。 For example, you could use the ALTER TABLE tablename ADD COLUMN your_new_column column_type (you can use DEFAULT value to set the columns to default values). 例如,您可以使用ALTER TABLE tablename ADD COLUMN your_new_column column_type (可以使用DEFAULT value将列设置为默认值)。

eg 例如

 ALTER TABLE mytable ADD COLUMN mynewcolumn TEXT DEFAULT 'nothing as yet' 

would Add a column called mynewcolumn , with a column type(affinity) of TEXT, to the table named mytable and all rows would have the value nothing as yet . 将添加一个名为mynewcolumn柱,用TEXT的列类型(关联),以名为MyTable的表和所有行会具有什么价值尚未

Note! 注意! all the above assume that you are using a Database Helper (ie a subclass of the SQLiteOpenHelper class ((ie it extends SQLiteOpenHelper))). 以上所有假定您正在使用数据库助手(即SQLiteOpenHelper类的子类((即它扩展了SQLiteOpenHelper)))。

Alternative issue 替代问题

If you are using ALTER to add a column there are some restrictions. 如果使用ALTER添加列,则存在一些限制。

You cannot add a column that has UNIQUE or PRIMARY INDEX constraints. 您不能添加具有UNIQUE或PRIMARY INDEX约束的列。 As your column name indicates an id column then you may well have tried something like 由于您的列名表示一个id列,因此您可能已经尝试过类似

String youraltersql = "ALTER TABLE "+TRANSACTIONS_TABLE_NAME+" ADD COLUMN " + SUB_CATEGORY_ID_COL + " INTEGER PRIMARY KEY"

this would not work, due to INTEGER PRIMARY KEY (same if you have AUTOINCREMENT). 由于INTEGER PRIMARY KEY(如果具有AUTOINCREMENT,则相同),此操作将不起作用。

SQL As Understood By SQLite - ALTER TABLE SQLite理解的SQL-ALTER TABLE

You Updated your table while adding new Column after table crated, so you have to Implement override method, have look this : 您在创建表格之后在添加新Column的同时更新了表格,因此您必须实现Override方法,如下所示:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  // If you need to add a column
  if (newVersion > oldVersion) {
     db.execSQL("ALTER TABLE "Your Table name"ADD COLUMN "new column "INTEGER DEFAULT 0");
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM