坚持"没有这样的栏目错误"将ListActivity与LoaderCallbacks一起使用时

时间:2014-03-13 08:15:56

标签: android sql sqlite

我的问题非常小,但我似乎无法找到解决方案。下面是我的代码然后我解释了我的问题。

MetersActivity

public class MetersActivity extends ListActivity implements LoaderCallbacks<Cursor>{
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.meters_list);

    this.getListView().setDividerHeight(2);

    fillData();

    registerForContextMenu(getListView());
}
private void fillData() {
    // Fields from the database (projection)
    // Must include the _id column for the adapter to work

      LoaderManager lm = getLoaderManager();

    String[] dataColumns = {"_id ", " meterNumber " };
    int[] meter = { R.id.meter_number_label};

    adapter = new SimpleCursorAdapter(this, R.layout.meter_row,
            null, dataColumns, meter, 0);

    setListAdapter(adapter);

    lm.initLoader(LOADER_ID, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id,
        Bundle args) {

    String[] PROJECTION = new String[] { "_id ", " meterNumber "};
    CursorLoader cursorLoader = new CursorLoader(MetersActivity.this,UserAccountsContentProvider.CONTENT_URI,PROJECTION, null, null, null);

     return cursorLoader;

}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

    // A switch-case is useful when dealing with multiple Loaders/IDs
    switch (loader.getId()) {
      case LOADER_ID:
        // The asynchronous load is complete and the data
        // is now available for use. Only now can we associate
        // the queried Cursor with the SimpleCursorAdapter.
        adapter.swapCursor(data);
        break;
    }


}


@Override
public void onLoaderReset(Loader<Cursor> loader) {
    // data is not available anymore, delete reference
    adapter.swapCursor(null);

}
}

我创建表格的课程:

// Database creation SQL statement for meters table
private static final String CREATE_TABLE_METERS = "create table " 
        + TABLE_METERS
        + "(" 
        + METER_ID + " integer primary key autoincrement, " 
        + METER_NUMBER + " integer not null, " 
        + PLOT_NUMBER + " varchar not null, "
        + COLUMN_CATEGORY + " varchar not null "
        + ");";


// Database creation SQL statement for customers table
private static final String CREATE_TABLE_CUSTOMERS = "create table " 
        + TABLE_CUSTOMERS
        + "(" 
        + KEY_CUSTOMER_ID + " integer primary key autoincrement, " 
        + KEY_FIRST_NAME + " text, " 
        + KEY_LAST_NAME + " text, "
        + KEY_ADDRESS + " varchar, "
        + KEY_EMAIL + " varchar, "
        + KEY_PHONE_NUMBER + " integer, "
        + KEY_ACCOUNT_NUMBER + " integer, "
        + KEY_METER_ID + " integer not null, "
        + KEY_METER_NUMBER + " integer not null, "
        + KEY_PLOT_NUMBER + " varchar not null, "
        +" FOREIGN KEY ("+KEY_METER_ID+") REFERENCES "+TABLE_METERS+" ("+METER_ID+"), " 
        +" FOREIGN KEY ("+KEY_METER_NUMBER+") REFERENCES "+TABLE_METERS+" ("+METER_NUMBER+"), " 
        +" FOREIGN KEY ("+KEY_PLOT_NUMBER+") REFERENCES "+TABLE_METERS+" ("+PLOT_NUMBER+"));"
        + ");"; 


// Database creation SQL statement for water bills table

private static final String CREATE_TABLE_WATERBILL = "create table " 
        + TABLE_WATER_BILL
        + "(" 
        + BILL_ID + " integer primary key autoincrement, "
        + BILL_NUMBER + " integer, "
        + KEY_BILLING_DATE + " date, " 
        + KEY_PREVIOUS_READING + " integer, "
        + KEY_CURRENT_READING+ " integer, "
        + KEY_DATEOF_READING + " date, "
        + KEY_CONSUMPTION + " integer, "
        + KEY_DUE_DATE  + " date, "
        + KEY_BILL_ITEMS + " varchar, "
        +  KEY_RATE + " integer, "
        +  KEY_CHARGES + " integer, "
        +  KEY_CONSUMPTION_PERIOD + " date, "
        +  KEY_TOTAL_DUE + " integer, "
        +  BILL_METER_ID + " integer not null, "
        + " FOREIGN KEY ("+BILL_METER_ID+") REFERENCES "+TABLE_CUSTOMERS+" ("+KEY_METER_ID+"));"
        + ");"; 


public static void onCreate(SQLiteDatabase database){
database.execSQL(CREATE_TABLE_METERS);
    database.execSQL(CREATE_TABLE_CUSTOMERS);
    database.execSQL(CREATE_TABLE_WATERBILL);
}

我的 Logcat输出

03-13 10:45:29.058: E/SQLiteLog(827): (1) no such column: meterNumber
03-13 10:45:29.158: E/AndroidRuntime(827): FATAL EXCEPTION: AsyncTask #1
03-13 10:45:29.158: E/AndroidRuntime(827): java.lang.RuntimeException: An error occured while executing    doInBackground()
03-13 10:45:29.158: E/AndroidRuntime(827):  at android.os.AsyncTask$3.done(AsyncTask.java:299)
03-13 10:45:29.158: E/AndroidRuntime(827):  at  java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
03-13 10:45:29.158: E/AndroidRuntime(827):  at   java.util.concurrent.FutureTask.setException(FutureTask.java:219)
03-13 10:45:29.158: E/AndroidRuntime(827): Caused by: android.database.sqlite.SQLiteException: no such  column: meterNumber (code 1): , while compiling: SELECT _id ,  meterNumber  FROM waterbills
03-13 10:45:29.158: E/AndroidRuntime(827):  at  android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)

问题

我正在尝试使用ContentProvider从SQLite中检索数据,并将其显示为列表。我有一个列表活动,它实现了LoaderCallbacks.I检查了大量的教程,甚至跟着一些信件,但我的应用程序崩溃了有一些原因。我在主活动上有一个用于显示客户列表的按钮。当我点击按钮时,我应该去一个单独的活动,它显示了我的名字列表,但是在点击后它崩溃了按钮,“编译时没有这样的列......”错误。

我有三张桌子 - 顾客,米和水潭。列meterNumber列在表格表中,但我注意到错误表明在表格水中没有找到“meterNumber”列!所以我想知道为什么它首先引用了那个但我已经检查了代码它似乎没关系。我也已经分别卸载了应用程序,增加了数据库版本但仍然无法正常工作。有时候额外的一组眼睛只是有助于看到我们没有的东西。我真的很感激一些帮助。

使用内容提供商类进行编辑

public class UserAccountsContentProvider extends ContentProvider{
private DatabaseHandler database;

    // Used for the UriMacher
    private static final int all_meters = 10;
    private static final int single_meter = 20;

    private static final int all_customers = 30;
    private static final int single_customer = 40;

    private static final int all_bills = 50;
    private static final int single_bill = 60;


    private static final String AUTHORITY = "com.isys.waterbillingsystem.contentprovider";



    //table meters

    private static final String METER_PATH = "meters";

    public static final Uri CONTENT_URI_METER = Uri.parse("content://" + AUTHORITY
            + "/" + METER_PATH);

    public static final String CONTENT_METER_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
              + "/meters";
    public static final String CONTENT_ITEM_METER_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
              + "/meter";

    //table customers

    private static final String CUSTOMERS_PATH = "customers";

    public static final Uri CONTENT_URI_CUSTOMERS = Uri.parse("content://" + AUTHORITY
            + "/" + CUSTOMERS_PATH);

    public static final String CONTENT_CUSTOMER_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
              + "/customers";
    public static final String CONTENT_ITEM_CUSTOMER_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
              + "/customer";

    //table waterbills

    private static final String BILL_PATH = "bills";

    public static final Uri CONTENT_URI_WATERBILLS = Uri.parse("content://" + AUTHORITY
            + "/" + BILL_PATH);



    private static final UriMatcher sURIMatcher = new UriMatcher(
            UriMatcher.NO_MATCH);
    static {
        sURIMatcher.addURI(AUTHORITY, METER_PATH, all_meters);
        sURIMatcher.addURI(AUTHORITY, METER_PATH + "/#", single_meter);

        sURIMatcher.addURI(AUTHORITY, CUSTOMERS_PATH, all_customers);
        sURIMatcher.addURI(AUTHORITY, CUSTOMERS_PATH + "/#", single_customer);

        sURIMatcher.addURI(AUTHORITY, BILL_PATH, all_bills);
        sURIMatcher.addURI(AUTHORITY, BILL_PATH + "/#", single_bill);

    }

    @Override
    public boolean onCreate() {
        try {

            database = new DatabaseHandler(getContext());

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {

        SQLiteDatabase db = database.getWritableDatabase();

        // Using SQLiteQueryBuilder instead of query() method
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

        queryBuilder.setTables(MeterTableDetails.TABLE_METERS);

        queryBuilder.setTables(CustomerTableDetails.TABLE_CUSTOMERS);

        queryBuilder.setTables(WaterBillTableDetails.TABLE_WATER_BILL);


        int uriType = sURIMatcher.match(uri);
        switch (uriType) {
        case all_meters:
            break;
        case single_meter:
            // Adding the ID to the original query

            String id = uri.getPathSegments().get(1);
            queryBuilder.appendWhere(MeterTableDetails.METER_ID + "=" + id);

            break;

        case all_customers:
            break;
        case single_customer:
            // Adding the ID to the original query
            String id1 = uri.getPathSegments().get(1);
            queryBuilder.appendWhere(CustomerTableDetails.KEY_CUSTOMER_ID + "=" + id1);
            break;

        case all_bills:
            break;
        case single_bill:
            // Adding the ID to the original query
            String id2 = uri.getPathSegments().get(1);
            queryBuilder.appendWhere(WaterBillTableDetails.BILL_ID + "=" + id2);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }

        Cursor cursor = queryBuilder.query(db, projection, selection,
                selectionArgs, null, null, sortOrder);
        // Make sure that potential listeners are getting notified
        cursor.setNotificationUri(getContext().getContentResolver(), uri);

        return cursor;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        int uriType = sURIMatcher.match(uri);
        SQLiteDatabase sqlDB = database.getWritableDatabase();

        long id = 0;

        switch (uriType) {
        case all_meters:
            id = sqlDB.insert(MeterTableDetails.TABLE_METERS, null, values);

            break;

        case all_customers:

            id = sqlDB.insert(CustomerTableDetails.TABLE_CUSTOMERS, null, values);

            break;

        case all_bills:

            id = sqlDB.insert(WaterBillTableDetails.TABLE_WATER_BILL, null, values);

            break;


        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return Uri.parse(METER_PATH + "/" + id);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int uriType = sURIMatcher.match(uri);
        SQLiteDatabase db = database.getWritableDatabase();

        switch (uriType) {
        case all_meters:
            break;
        case single_meter:

            String id = uri.getPathSegments().get(1);
            selection = MeterTableDetails.METER_ID
                    + "="
                    + id
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                            + ')' : "");

            break;

        case all_customers:
            break;
        case single_customer:

            String id1 = uri.getPathSegments().get(1);
            selection = CustomerTableDetails.KEY_CUSTOMER_ID
                    + "="
                    + id1
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                            + ')' : "");
            break;

        case all_bills:
            break;
        case single_bill:

            String id2 = uri.getPathSegments().get(1);
            selection = WaterBillTableDetails.BILL_ID
                    + "="
                    + id2
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                            + ')' : "");
            break;


        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }

        int deleteCount;
        deleteCount = db.delete(MeterTableDetails.TABLE_METERS, selection,
                selectionArgs);

        deleteCount = db.delete(CustomerTableDetails.TABLE_CUSTOMERS, selection,
                selectionArgs);

         deleteCount = db.delete(WaterBillTableDetails.TABLE_WATER_BILL, selection,
         selectionArgs);


        getContext().getContentResolver().notifyChange(uri, null);

        return deleteCount;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {

        int uriType = sURIMatcher.match(uri);
        SQLiteDatabase db = database.getWritableDatabase();

        switch (uriType) {
        case all_meters:

            break;
        case single_meter:

            String id = uri.getPathSegments().get(1);
            selection = MeterTableDetails.METER_ID
                    + "="
                    + id
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                            + ')' : "");

            break;

        case all_customers:

            break;
        case single_customer:

            String id1 = uri.getPathSegments().get(1);
            selection = CustomerTableDetails.KEY_CUSTOMER_ID
                    + "="
                    + id1
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                            + ')' : "");

            break;

        case all_bills:

            break;
        case single_bill:

            String id2 = uri.getPathSegments().get(1);
            selection = WaterBillTableDetails.BILL_ID
                    + "="
                    + id2
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                            + ')' : "");

            break;

        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }

        int updateCount;

        updateCount = db.update(MeterTableDetails.TABLE_METERS, values,
                selection, selectionArgs);
        getContext().getContentResolver().notifyChange(uri, null);

        updateCount = db.update(CustomerTableDetails.TABLE_CUSTOMERS, values, selection,
                selectionArgs);
        getContext().getContentResolver().notifyChange(uri, null);

         updateCount = db.update(WaterBillTableDetails.TABLE_WATER_BILL, values, selection,
         selectionArgs);



        return updateCount;
    }


}

1 个答案:

答案 0 :(得分:1)

因此表MeterNumber中没有waterbills列:

private static final String CREATE_TABLE_WATERBILL = "create table " 

+ TABLE_WATER_BILL
+ "(" 
+ BILL_ID + " integer primary key autoincrement, "
+ BILL_NUMBER + " integer, "
+ KEY_BILLING_DATE + " date, " 
+ KEY_PREVIOUS_READING + " integer, "
+ KEY_CURRENT_READING+ " integer, "
+ KEY_DATEOF_READING + " date, "
+ KEY_CONSUMPTION + " integer, "
+ KEY_DUE_DATE  + " date, "
+ KEY_BILL_ITEMS + " varchar, "
+  KEY_RATE + " integer, "
+  KEY_CHARGES + " integer, "
+  KEY_CONSUMPTION_PERIOD + " date, "
+  KEY_TOTAL_DUE + " integer, "
+  BILL_METER_ID + " integer not null, "
+ " FOREIGN KEY ("+BILL_METER_ID+") REFERENCES "+TABLE_CUSTOMERS+" ("+KEY_METER_ID+"));"
+ ");"; 

您还在等什么查询?

在您的数据提供程序中设置表格,这些表格将在查询中使用:

 queryBuilder.setTables(MeterTableDetails.TABLE_METERS);

 queryBuilder.setTables(CustomerTableDetails.TABLE_CUSTOMERS);

 queryBuilder.setTables(WaterBillTableDetails.TABLE_WATER_BILL);

这是错的。查询将仅在WATER_BILL表上进行。如果您想从多个表use JOIN获取数据:

queryBuilder.setTables(MeterTableDetails.TABLE_METERS INNER JOIN CustomerTableDetails.TABLE_CUSTOMERS ON (....));