SQLite テーブルにいくつかのレコードを追加しようとしていますが、LogCat からテーブルが存在しないと表示されます。そしてDDMSは、はい、そのテーブルが作成されていない/作成されていないことを示しています。
それでも、SQLiteOpenHelper クラスでテーブルを作成します。
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);
}
レコードを追加するクラスのメソッドを呼び出します。
SQLiteHandlerDeliveryItem sqliteHandler = new SQLiteHandlerDeliveryItem(SQLiteActivity.this, null);
sqliteHandler.addDeliveryItem(delItem);
これは SQLiteHandlerDeliveryItem のコンストラクターを呼び出す必要があります (sqliteHandler がインスタンス化されている場合) が、そうではありません! onCreate() メソッドにブレークポイントを設定しましたが、確かに到達していません。
なんで?テーブルが作成されるように、コンストラクターを強制的に呼び出すにはどうすればよいですか?
奇妙なのは、他の (動作中の) SQLiteOpenHelper クラスにもブレークポイントを設定したことです。テーブルが存在する/そのコードから作成されたため、少なくとも1回は機能しました。
だから、私のスイングには明らかに穴があります。私は何を誤解しているか間違っていますか?
アップデート
私は答えをTHE答えとしてマークしました。
に関して:
「1. ある時点で getWritableDatabase() または getReadableDatabase() を呼び出す必要があります。」
次のように、レコードを作成または読み取る各メソッドで getWritableDatabase() を呼び出します。
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);
}
. . .
...そして、に関して:
「2. SQLiteHandlerDeliveryItem のコンストラクターでは、super(...) を呼び出す必要があります。」
SQLiteOpenHelper を拡張するクラスで super を呼び出します。
public SQLiteHandlerDeliveryItem(Context context, SQLiteDatabase.CursorFactory factory)
{
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
だから...私はまだ問題/解決策が何であるかわかりません...
更新 2
したがって、LogCat でこのテーブルにレコードを挿入しようとすると、次のようになります。
E/SQLiteLog﹕ (1) no such table: deliveryitems
それでも、レコードを追加しようとする私のコードは、次のように SQLiteOpenHelper を拡張する対応する/適切なクラスをインスタンス化します。
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);
}
}
...そして、そのクラスにはテーブルを作成するコードがあります:
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);
}
それで...私は何を間違っているのですか、それとも正しいことをしていないのですか?
更新 3
テーブルが作成されていないのは事実です。LogCat の err メッセージは、その場合であることを示しています (「そのようなテーブルはありません: deliveryitems」です)。
私のコンストラクタは次のようになります。
@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);
}
実際、このコードは入力されません。では、コンストラクターを呼び出すには、どのフープを通過する必要がありますか?
クラスをインスタンス化すると、次のようになると思います。
SQLiteHandlerDeliveryItem sqliteHandler = new
SQLiteHandlerDeliveryItem(SQLiteActivity.this, null);
呼び出された場合でも、コンストラクターは引数 (SQLiteDatabase db) が何であるかをどのように認識しますか? この値はどこから取得しますか?
私は1つのテーブルを持つデータベースを持っています。この 2 番目のテーブルの追加を拒否するだけです。
どこかで推奨されているように、データベースに追加するテーブルごとに SQLiteOpenHelper を拡張する別のクラスを追加しています。
その行に到達すると:
SQLiteHandlerDeliveryItem sqliteHandler = new
SQLiteHandlerDeliveryItem(SQLiteActivity.this, null);
...そして F7 を押してステップインすると、クラス コンストラクターに到達します。
public SQLiteHandlerDeliveryItem(Context context, SQLiteDatabase.CursorFactory factory)
{
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
...しかし、onCreate イベントではありません。
したがって、deliveryitems テーブルを作成するコードに到達しないのは「当然」です。しかし、なぜ到達しないのですか - 到達させるにはどうすればよいですか?