问题描述
我想一些记录添加到一个SQLite表,但LogCat中告诉我的表不存在。和DDMS表明,是的,没有被/尚未创建该表。
I'm trying to add some records to a SQLite table, but LogCat is telling me the table does not exist. And DDMS shows that, yes, that table is not being/has not been created.
但我确实创造了SQLiteOpenHelper类表:
Yet I do create the table in the SQLiteOpenHelper class:
public class SQLiteHandlerDeliveryItem extends SQLiteOpenHelper {
. . .
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String CREATE_DELIVERYITEMS_TABLE = "CREATE TABLE " +
TABLE_DELIVERYITEMS + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_INVOICENUM + " TEXT,"
+ COLUMN_UPCPLU + " TEXT," + COLUMN_VENDORITEMID + " TEXT,"
+ COLUMN_PACKSIZE + " INTEGER," + COLUMN_DESCRIPTION + " TEXT,"
//+ COLUMN_COST + " REAL," + COLUMN_MARGIN + " REAL," + COLUMN_LISTPRICE + " REAL,"
+ COLUMN_COST + " REAL DEFAULT 0," + COLUMN_MARGIN + " REAL DEFAULT 0," +
COLUMN_LISTPRICE + " REAL DEFAULT 0,"
+ COLUMN_DEPTNUM + " INTEGER," + COLUMN_SUBDEPT + " TEXT," + COLUMN_QTY + " TEXT"
+ ")";
sqLiteDatabase.execSQL(CREATE_DELIVERYITEMS_TABLE);
}
我调用类的方法,这将增加记录:
I call the class's method which adds records:
SQLiteHandlerDeliveryItem sqliteHandler = new SQLiteHandlerDeliveryItem(SQLiteActivity.this, null);
sqliteHandler.addDeliveryItem(delItem);
这应该叫SQLiteHandlerDeliveryItem的构造函数(当sqliteHandler被实例化),但它不会!我有一个断点在onCreate()方法,果然 - 它从来没有达到
This should call SQLiteHandlerDeliveryItem's constructor (when sqliteHandler is instantiated), but it doesn't! I've got a breakpoint in the onCreate() method, and sure enough - it's never reached.
为什么呢?我怎么能强制构造函数被调用,从而创建表?
Why? And how can I force the constructor to be called, so that the table is created?
奇怪[EST]的事情是,我也把一个断点在另一个(工作)SQLiteOpenHelper类,它的也的没有达到......什么?!?它的工作至少一次,因为的确存在表/是从code创建的。
The odd[est] thing is that I also put a breakpoint in the other (working) SQLiteOpenHelper class, and it is also not reached...what?!? It worked at least once, as the table does exist/was created from that code.
因此,有明显somehwere我的挥杆一个洞;我是什么误会或做错了吗?
So there's obviously a hole in my swing somehwere; what am I misunderstanding or doing wrong?
我太早标志着答案答案。
I marked the answer as THE answer too soon.
至于
的1。你必须在某个时候调用getWritableDatabase()或getReadableDatabase()。的
我的做的每个创建或读取的记录,像这样的方法调用getWritableDatabase():
I do call getWritableDatabase() in each method that creates or reads records, like so:
public long addDeliveryItem(DeliveryItem delItem) {
long IdAdded = 0;
ContentValues values = new ContentValues();
values.put(COLUMN_INVOICENUM, delItem.get_invoiceNumber());
. . .
values.put(COLUMN_QTY, delItem.get_quantity());
SQLiteDatabase db = this.getWritableDatabase(); <= Rot Cheer
if (db != null) {
IdAdded = db.insert(TABLE_DELIVERYITEMS, null, values);
}
. . .
...并在以下方面:
...and as regards:
的2,在您的构造SQLiteHandlerDeliveryItem,必须调用super(...)。的
我的做的在扩展SQLiteOpenHelper类调用超:
I do call super in the class that extends SQLiteOpenHelper:
public SQLiteHandlerDeliveryItem(Context context, SQLiteDatabase.CursorFactory factory)
{
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
所以...我还是不知道的问题/解决方案是什么...
So...I still don't know what the problem/solution is...
所以,我看到试图插入一条记录到该表中LogCat中时是:
So what I see when attempting to insert a record into this table in LogCat is:
E / SQLiteLog:(1)没有这样的表:deliveryitems 的
不过,我的code,试图添加记录实例化扩展SQLiteOpenHelper像这样对应的/合适的类:
Yet my code that attempts to add the record instantiates the corresponding/appropriate class that extends SQLiteOpenHelper like so:
else if ("Delivery Items".equals(tableName)) {
try {
JSONArray jsonArr = new JSONArray(result);
for (int i = 0; i < jsonArr.length(); i++) {
JSONObject jsonObj = jsonArr.getJSONObject(i);
String invNum = jsonObj.getString("invoiceNumber");
. . .
// Prepare for writing to db
DeliveryItem delItem = new DeliveryItem();
delItem.set_invoiceNumber(invNum);
. . .
SQLiteHandlerDeliveryItem sqliteHandler = new
SQLiteHandlerDeliveryItem(SQLiteActivity.this, null);
sqliteHandler.addDeliveryItem(delItem);
}
}
...那类有code创建表:
...and that class has the code to create the table:
public class SQLiteHandlerDeliveryItem extends SQLiteOpenHelper {
. . .
public SQLiteHandlerDeliveryItem(Context context, SQLiteDatabase.CursorFactory factory)
{
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String CREATE_DELIVERYITEMS_TABLE = "CREATE TABLE " +
TABLE_DELIVERYITEMS + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_INVOICENUM + " TEXT,"
+ COLUMN_UPCPLU + " TEXT," + COLUMN_VENDORITEMID + " TEXT,"
+ COLUMN_PACKSIZE + " INTEGER," + COLUMN_DESCRIPTION + " TEXT,"
+ COLUMN_COST + " INTEGER," + COLUMN_MARGIN + " INTEGER," + COLUMN_LISTPRICE + " INTEGER,"
+ COLUMN_DEPTNUM + " INTEGER," + COLUMN_SUBDEPT + " TEXT," + COLUMN_QTY + " TEXT"
+ ")";
sqLiteDatabase.execSQL(CREATE_DELIVERYITEMS_TABLE);
}
所以...我是什么做错了,或者没有做对吗?
So...what am I doing wrong, or failing to do right?
这是真的没有被创建的表。在LogCat中的错误消息表明,是这种情况(它的没有这样的表:delivertitems)。
It's true the table is not being created. The err msg in LogCat indicates that to be the case (it's "no such table: delivertitems").
我的构造函数如下:
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_DELIVERYITEMS_TABLE = "CREATE TABLE " +
TABLE_DELIVERYITEMS + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_INVOICENUM + " TEXT,"
+ COLUMN_UPCPLU + " TEXT," + COLUMN_VENDORITEMID + " TEXT,"
+ COLUMN_PACKSIZE + " INTEGER," + COLUMN_DESCRIPTION + " TEXT,"
+ COLUMN_COST + " INTEGER," + COLUMN_MARGIN + " INTEGER," + COLUMN_LISTPRICE + " INTEGER,"
+ COLUMN_DEPTNUM + " INTEGER," + COLUMN_SUBDEPT + " TEXT," + COLUMN_QTY + " TEXT"
+ ")";
db.execSQL(CREATE_DELIVERYITEMS_TABLE);
}
这code呢,确实的不的得到输入。那么,什么箍必须跨越我通过获得构造函数被调用?
This code does, indeed, not get entered. So what hoop must I leap through to get the constructor to be called?
我想,当我实例化类,会发生:
I would think that would happen when I instantiate the class:
SQLiteHandlerDeliveryItem sqliteHandler = new
SQLiteHandlerDeliveryItem(SQLiteActivity.this, null);
甚至当它被调用时,如何构造知道ARG(SQLiteDatabase DB)是 - 在它与得到这个值
Even when it is called, how does the constructor know what the arg (SQLiteDatabase db) is - where does it get this value from?
我有一个数据库,一个表。它只是拒绝添加这个第二个表。
I do have a database, with one table. It just refuses to add this second table.
由于有人的地方推荐,我加入了扩展SQLiteOpenHelper因为我想要添加到数据库中每个表一个单独的类。
As someone somewhere recommended, I'm adding a separate class that extends SQLiteOpenHelper for each table I want to add to the database.
当我到该行:
SQLiteHandlerDeliveryItem sqliteHandler = new
SQLiteHandlerDeliveryItem(SQLiteActivity.this, null);
...和土豆泥F7踏进去,我到了类的构造函数:
...and mash F7 to step into it, I reach the class constructor:
public SQLiteHandlerDeliveryItem(Context context, SQLiteDatabase.CursorFactory factory)
{
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
...但不onCreate事件。
...but not the onCreate event.
所以它是难怪我没有deliveryitems表,为code创建表说,从来没有得到达;但为什么它没有得到达 - ?我该怎么做才能让它达到
So it's "no wonder" I have no deliveryitems table, as the code to create said table never gets reached; but WHY does it not get reached - what must I do to get it to BE reached?
推荐答案
正如我希望的,它实际上原来是一个简单的办法:只需增加你的数据库版本值。我读这页上。
As I was hoping, it actually turns out to be an easy fix: simply increment the value of your database version. I read this on p. 262 of O'Reilly's "Programming Android":
的 DATABASE_VERSION
...如果数据库的机器上的版本低于DATABASE_VERSION,系统运行的onUpgrade方法升级数据库的当前水平。的
因此,所有你需要做的是增量,编号:
Thus, all you need to do is increment that number:
private static final int DATABASE_VERSION = 2;
// I changed it from "1" to "2", but you could change it to anything you want, I reckon (42, or 1776, or whatever).
递增的版本值会导致onUpgrade运行,这将删除旧版本的数据库,然后调用的onCreate:
Incrementing the version value causes onUpgrade to run, which drops the old version of the database and then calls onCreate:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_DELIVERYITEMS);
onCreate(db);
}
本的onCreate()事件则正是这么做的 - 添加DDL创建表
The onCreate() event then does exactly that - adding the DDL to create the table.
下面是在上下文中扩展SQLiteOpenHelper类相关code:
Here is the pertinent code in the class that extends SQLiteOpenHelper in context:
public class SQLiteHandlerDeliveryItem extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "HHS.db";
private static final String TABLE_DELIVERYITEMS = "deliveryitems";
private static final String COLUMN_ID = "_id";
. . .
private static final String COLUMN_QTY = "quantity";
public SQLiteHandlerDeliveryItem(Context context, SQLiteDatabase.CursorFactory factory)
{
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_DELIVERYITEMS_TABLE = "CREATE TABLE " +
TABLE_DELIVERYITEMS + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_INVOICENUM + " TEXT,"
. . .
+ COLUMN_DEPTNUM + " INTEGER," + COLUMN_SUBDEPT + " TEXT," + COLUMN_QTY + "
TEXT"
+ ")";
db.execSQL(CREATE_DELIVERYITEMS_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_DELIVERYITEMS);
onCreate(db);
}
. . .
所以,在我看来具有延伸SQLiteOpenHelper是一件好事,因为你可以从而保持您的code分离,而不是有一个巨大的/堆积如山对onUpgrade /意大利面条的onCreate多类。
So it seems to me having multiple classes that extend SQLiteOpenHelper is a good thing, since you can thus keep your code separated, rather than have one gigantic/humongous pair of onUpgrade/onCreate spaghetti.
这篇关于为什么我的构造没有得到叫什么名字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!