Android的SQLite的列未找到错误当执行原始查询 [英] Android SQLite Column Not Found Error When Executing Raw Query

查看:299
本文介绍了Android的SQLite的列未找到错误当执行原始查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提出一个Android应用程序搜索餐馆SQLite数据库。我目前使用的自定义加载器(即我在网上找到),以从数据库中加载一个光标,然后采取光标和填充用SimpleCursorAdapter列表视图。我希望所有的数据绑定,而是只显示餐厅的名字(因为当我点击我想获得的所有数据,并将其发送到显示的数据的新的活动列表项)。如果我指定的餐馆名称和餐厅类型作为搜索参数,我运行原始查询:

 SELECT * FROM餐厅,名字=+名字+和舍入类型=+ restaurantType;

在我SQLiteCursorLoader类,我得到一个错误,指出该列舍入类型不存在,甚至以为我知道列酒楼表中存在。看来,当我在查询的两个WHERE子句,我得到这个错误,但是当我有一个WHERE子句,这种情况不会发生。任何帮助将不胜AP preciated!这里是我的code:

RestuarantSearchResultsActivity:

 包com.studentapplication;
进口android.app.Activity;
进口android.app.ListActivity;
进口android.app.LoaderManager;
进口android.content.Loader;
进口android.database.Cursor;
进口android.os.Bundle;
进口android.util.Log;
进口android.view.View;
进口android.widget.ListView;
进口android.widget.SimpleCursorAdapter;公共类RestaurantSearchResultsActivity扩展ListActivity工具
LoaderManager.LoaderCallbacks<&光标GT; {DatabaseHelper databaseHelper;
SimpleCursorAdapter mAdapter;
捆绑searchParameters;@覆盖
公共无效的onCreate(捆绑savedInstanceState)
{
    Log.w(CoolBeans,结果活动创建);
    super.onCreate(savedInstanceState);    databaseHelper =新DatabaseHelper(getApplicationContext());
    //setContentView(R.layout.restaurant_search_results);    捆绑searchParameters = getIntent()getExtras()。
    字符串n = searchParameters.getString(名称);
    Log.i(0)中,n);
    //第N列应首先匹配toViews N个视点
    的String [] = fromColumns {的getString(R.string.database_column_name)
                           的getString(R.string.database_column_restaurant_type)
                           的getString(R.string.database_column_phone_number)
                           的getString(R.string.database_column_address)
               的getString(R.string.database_column_csz)
               的getString(R.string.database_column_brief_description)
               的getString(R.string.database_column_url)
               的getString(R.string.database_column_price)};    INT [] = toViews {android.R.id.text1};    mAdapter =新SimpleCursorAdapter(getApplicationContext()
                        this.getListView()。的getId(),
                        空值,
                            fromColumns,
                        toViews,
                        0);
    setListAdapter(mAdapter);
    getLoaderManager()initLoader(0,searchParameters,这一点)。
}@覆盖
公共装载机<&光标GT; onCreateLoader(INT ID,捆绑searchParameters){
    Log.i(3),正确的装载机在建);
    返回新SQLiteCursorLoader(getApplicationContext()
            databaseHelper,
            sea​​rchParameters,
            空值);}@覆盖
公共无效onLoadFinished(装载机<&光标GT;装载机,游标数据){
    mAdapter.swapCursor(数据);}@覆盖
公共无效onLoaderReset(装载机<&光标GT;装载机){
    mAdapter.swapCursor(NULL);}@覆盖
    公共无效onListItemClick(ListView中升,视图V,INT位置,长的ID)
{
    光标myCursor =(光标)l.getItemAtPosition(位置);
    如果(l.isItemChecked(位置)==真)
    {
        l.setItemChecked(位置,FALSE);
        //关闭previously所选项目的详细信息    }
    其他
    {
        l.setItemChecked(位置,真正的);        //启动previously所选项目的详细信息    }
}
}

SQLiteCursorLoader:

 包com.studentapplication;进口java.io.FileDescriptor中;
进口的java.io.PrintWriter;
进口java.util.Arrays中;
进口android.content.ContentValues​​;
进口android.content.Context;
进口android.content.res.Resources;
进口android.database.Cursor;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteOpenHelper;
进口android.database.sqlite.SQLiteQueryBuilder;
进口android.os.Bundle;
进口android.util.Log;公共类SQLiteCursorLoader扩展AbstractCursorLoader
{
SQLiteOpenHelper DB = NULL;
字符串rawQuery = NULL;
字串[] args = NULL;/ **
 *创建一个完全指定SQLiteCursorLoader。看到
 * {@link SQLiteDatabase#rawQuery(SQLiteDatabase,字符串,字符串[])
 * SQLiteDatabase.rawQuery()}上的文档
 *参数的含义。这些将被原封不动的使用
 *这一号召。
 * /
公共SQLiteCursorLoader(上下文的背景下,SQLiteOpenHelper分贝,捆绑
    sea​​rchParameters,字串[] args)
{
    超级(上下文);
    this.db = DB;
    this.rawQuery =的createQuery(searchParameters);
    this.args = ARGS;
}私人字符串的createQuery(捆绑searchParameters){
    字符串名称=\\';
    名称=名称+ searchParameters.getString(名称);
    名称=名称+\\';
    INT价格= searchParameters.getInt(价格);
    字符串restaurantType =\\';
    restaurantType = restaurantType +
            sea​​rchParameters.getString(restaurant_type);
    restaurantType = restaurantType +\\';    //串DIST = searchParameters.getString(DIST);    串theQuery =;    如果(!name.equals(\\'\\'))
    {
        如果(!restaurantType.equals(\\_ \\))
        {
            theQuery =SELECT * FROM餐厅,名字
=+名字+和舍入类型=+ restaurantType;
        }
        否则,如果(价格!= 0)
        {
            theQuery =SELECT * FROM餐厅,名字=+名字
+,价格=+((整数)的价格)的ToString();
        }
        其他
        {
            theQuery =SELECT * FROM餐厅,名字=+名;
        }
    }
    否则,如果(!restaurantType.equals(\\'\\'))
    {
        theQuery =SELECT * FROM餐厅,TYPE =+
restaurantType +按名称排序;
    }
    否则,如果(价格!= 0)
    {
        theQuery =SELECT * FROM的餐厅,价格=+价格+SORT
按名字;
    }    返回theQuery;
}
/ **
 *运行在工作线程和执行实际
 *数据库查询检索光标。
 * /
@覆盖
保护光标buildCursor()
{
    回报(db.getReadableDatabase()rawQuery(rawQuery,参数));
}/ **
 *写的内容到一个半用户可读名册
 *提供的输出。
 * /
@覆盖
公共无效转储(字符串preFIX,FD FileDescriptor的,PrintWriter的作家的String []
    参数)
{
    super.dump(preFIX,FD,作家,参数);
    writer.print(preFIX);
    writer.print(rawQuery =);
    writer.println(rawQuery);
    writer.print(preFIX);
    writer.print(ARGS =);
    writer.println(Arrays.toString(参数));
}公共无效插入(字符串表,字符串nullColumnHack,ContentValues​​值)
{
    新InsertTask(本).execute(DB,桌子,nullColumnHack,价值观);
}公共无效更新(字符串表,ContentValues​​值,字符串whereClause,字符串[]
    whereArgs)
{
    新UpdateTask(本).execute(DB,表,价值观,whereClause,whereArgs);
}公共无效替换(字符串表,字符串nullColumnHack,ContentValues​​值)
{
    新ReplaceTask(本).execute(DB,桌子,nullColumnHack,价值观);
}公共无效删除(字符串表,字符串whereClause,字符串[] whereArgs)
{
    新DeleteTask活动(本).execute(DB,桌子,whereClause,whereArgs);
}公共无效execSQL(SQL字符串,对象[] bindArgs)
{
    新ExecSQLTask(本).execute(DB,SQL,bindArgs);
}//私人课程私有类InsertTask扩展ContentChangingTask<对象,太虚,太虚>
{
    InsertTask(SQLiteCursorLoader装载机)
    {
        超(装载机);
    }    @覆盖
    保护无效doInBackground(对象... PARAMS)
    {
        SQLiteOpenHelper分贝=(SQLiteOpenHelper)PARAMS [0];
        字符串表=(字符串)PARAMS [1];
        字符串nullColumnHack =(字符串)PARAMS [2];
        ContentValues​​值=(ContentValues​​)PARAMS [3];        。db.getWritableDatabase()插入(表,nullColumnHack,价值观);        回报(NULL);
    }
}私有类UpdateTask扩展ContentChangingTask<对象,太虚,太虚>
{
    UpdateTask(SQLiteCursorLoader装载机)
    {
        超(装载机);
    }    @覆盖
    保护无效doInBackground(对象... PARAMS)
    {
        SQLiteOpenHelper分贝=(SQLiteOpenHelper)PARAMS [0];
        字符串表=(字符串)PARAMS [1];
        ContentValues​​值=(ContentValues​​)PARAMS [2];
        字符串,其中=(字符串)PARAMS [3];
        的String [] = whereParams(字符串[])PARAMS [4];        db.getWritableDatabase()更新(表,值,其中,whereParams)。        回报(NULL);
    }
}私有类ReplaceTask扩展ContentChangingTask<对象,太虚,太虚>
{
    ReplaceTask(SQLiteCursorLoader装载机)
    {
        超(装载机);
    }    @覆盖
    保护无效doInBackground(对象... PARAMS)
    {
        SQLiteOpenHelper分贝=(SQLiteOpenHelper)PARAMS [0];
        字符串表=(字符串)PARAMS [1];
        字符串nullColumnHack =(字符串)PARAMS [2];
        ContentValues​​值=(ContentValues​​)PARAMS [3];        db.getWritableDatabase()取代(表,nullColumnHack,价值观)。        回报(NULL);
    }
}私有类DeleteTask活动扩展ContentChangingTask<对象,太虚,太虚>
{
    DeleteTask活动(SQLiteCursorLoader装载机)
    {
        超(装载机);
    }    @覆盖
    保护无效doInBackground(对象... PARAMS)
    {
        SQLiteOpenHelper分贝=(SQLiteOpenHelper)PARAMS [0];
        字符串表=(字符串)PARAMS [1];
        字符串,其中=(字符串)PARAMS [2];
        串[] whereParams =(串[])PARAMS [3];        db.getWritableDatabase()删除(表,其中,whereParams)。        回报(NULL);
    }
}私有类ExecSQLTask扩展ContentChangingTask<对象,太虚,太虚>
{
    ExecSQLTask(SQLiteCursorLoader装载机)
    {
        超(装载机);
    }    @覆盖
    保护无效doInBackground(对象... PARAMS)
    {
        SQLiteOpenHelper分贝=(SQLiteOpenHelper)PARAMS [0];
        串的SQL =(串)PARAMS [1];
        [对象] bindParams =(对象[])PARAMS [2];        。db.getWritableDatabase()execSQL(SQL,bindParams);     回报(NULL);
    }
}
}

AbstractCursorLoader:

 包com.studentapplication;进口android.annotation.TargetApi;
进口android.content.AsyncTaskLoader;
进口android.content.Context;
进口android.database.Cursor;
进口android.os.Build;@TargetApi(Build.VERSION_ codeS.HONEYCOMB)
抽象公共类AbstractCursorLoader扩展AsyncTaskLoader<&光标GT; {抽象保护光标buildCursor();
光标lastCursor = NULL;公共AbstractCursorLoader(上下文的背景下){
  超级(上下文);
}/ **
 *运行在一个工作者线程,在我们的数据加载。代表
 *实际工作中具体子'buildCursor()方法。
 * /
@覆盖
公共光标loadInBackground(){
  光标光标= buildCursor();  如果(指针!= NULL){
    //确保光标窗口填写
    cursor.getCount();
  }  返回(光标);
}/ **
 *运行在UI线程上,从路由的结果
 *后台线程无论是使用光标
 *(例如,CursorAdapter的)。
 * /
@覆盖
公共无效deliverResult(光标光标){
  如果(isReset()){
    //异步查询进来,而装载器停止
    如果(指针!= NULL){
      cursor.close();
    }    返回;
  }  光标oldCursor = lastCursor;
  lastCursor =光标;  如果(isStarted()){
    super.deliverResult(光标);
  }  如果(oldCursor = NULL&放大器;!&安培; oldCursor =光标和放大器;!&安培;!oldCursor.isClosed()){
    oldCursor.close();
  }
}/ **
 *启动列表数据的异步负载。
 *当结果已就绪回调会被调用
 *在UI线程。如果previous负荷已完成
 *和仍然有效的结果可以被传递到
 *立即回调。
 *
 *必须从UI线程调用。
 * /
@覆盖
保护无效onStartLoading(){
  如果(lastCursor!= NULL){
    deliverResult(lastCursor);
  }  如果(takeContentChanged()|| lastCursor == NULL){
    的forceload();
  }
}/ **
*必须从UI线程调用,通过触发
*调用stopLoading()。
* /
@覆盖
保护无效onStopLoading(){
  //尝试如果可能取消当前的负载任务。
  cancelLoad();
}/ **
 *必须从UI线程调用,通过触发
 *呼吁取消()。在这里,我们要确保我们的游标
 *关闭,如果它仍然存在,并且尚未关闭。
 * /
@覆盖
公共无效onCanceled(光标光标){
  如果(光标=空&放大器;!&放大器;!cursor.isClosed()){
    cursor.close();
  }
}/ **
 *必须从UI线程调用,通过触发
 *调用复位()。在这里,我们要确保我们的游标
 *关闭,如果它仍然存在,并且尚未关闭。
 * /
@覆盖
保护无效onReset(){
  super.onReset();  //确保装载机停止
  onStopLoading();  如果(lastCursor =空&放大器;!&放大器;!lastCursor.isClosed()){
    lastCursor.close();
  }  lastCursor = NULL;
  }
  }

DatabaseHelper:

 包com.studentapplication;进口android.content.Context;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteDatabase.CursorFactory;
进口android.database.sqlite.SQLiteOpenHelper;公共类DatabaseHelper扩展SQLiteOpenHelper {//所有静态变量
//数据库版本
私有静态最终诠释DATABASE_VERSION = 1;//数据库名称
私有静态最后弦乐DATABASE_NAME =LOCAL_DATABASE;//表名
私有静态最后弦乐TABLE_Restaurant =餐厅;
私有静态最后弦乐TABLE_Coupon =优惠券;
私有静态最后弦乐TABLE_Linker =链接;//餐厅列
私有静态最后弦乐R_Name =名;
私有静态最后弦乐R_Description =说明;
私有静态最后弦乐R_Address =地址;
私有静态最后弦乐R_CSZ =财税字;
私有静态最后弦乐R_URL =URL;
私有静态最后弦乐R_Price =价格;
私有静态最后弦乐R_TYPE =舍入类型;
私有静态最后弦乐R_ID =_id;//优惠券列
私有静态最后弦乐C_ID =_id;
私有静态最后弦乐C_NAME =名;
私有静态最后弦乐C_Description =说明;//连接表列
私有静态最后弦乐R_ID =R_ID;
私有静态最后弦乐C_ID =C_ID;
私有静态最后弦乐日期=日期;
私有静态最后弦乐l_id =l_id;公共DatabaseHelper(上下文的背景下)
{
    超(背景下,DATABASE_NAME,空,DATABASE_VERSION);}公共DatabaseHelper(上下文的背景下,字符串名称,CursorFactory厂,
        INT版){
    超(背景下,名称,厂家,版本);
}//创建表
@覆盖
公共无效的onCreate(SQLiteDatabase DB){
    字符串CREATE_Restaurant_TABLE =CREATE TABLE+ TABLE_Restaurant +(
            + R_ID +INTEGER PRIMARY KEY
            + R_Name +TEXT NOT NULL,
            + R_TYPE +TEXT NOT NULL,
            + R_Address +TEXT NOT NULL,
            + R_CSZ +TEXT NOT NULL,
            + R_Description +TEXT NOT NULL,
            + R_URL +TEXT NOT NULL,
            + R_Price +INTEGER NOT NULL
            +);    字符串CREATE_Coupon_TABLE =CREATE TABLE+ TABLE_Coupon +(
            + C_ID +INTEGER PRIMARY KEY
            + C_NAME +TEXT
            + C_Description +TEXT
            +);    字符串CREATE_Linker_TABLE =CREATE TABLE+ TABLE_Linker +(
            + R_ID +INTEGER
            + C_ID +INTEGER
            +日期+DATE
            + l_id +INTEGER PRIMARY KEY
            +外键(R_ID)参考文献餐厅(_id),
            +外键(C_ID)参考券(_id));    db.execSQL(CREATE_Restaurant_TABLE);
    db.execSQL(CREATE_Coupon_TABLE);
    db.execSQL(CREATE_Linker_TABLE);
}//数据库升级
@覆盖
公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
    如果存在//删除旧的表
    db.execSQL(DROP TABLE IF EXISTS+ TABLE_Restaurant);
    //再次创建表
    的onCreate(DB);
}}

堆栈跟踪:

  04-23 13:47:29.691:E / SQLiteLog(2600):(1)没有这样的列:舍入类型
04-23 13:47:29.691:W / dalvikvm(2600):主题ID = 11:螺纹未捕获退出
    异常(组= 0x40a13300)
04-23 13:47:29.852:E / AndroidRuntime(2600):致命异常:AsyncTask的#1
04-23 13:47:29.852:E / AndroidRuntime(2600):了java.lang.RuntimeException:错误
    发生在执行doInBackground()
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.os.AsyncTask $ 3.done(AsyncTask.java:299)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    java.util.concurrent.FutureTask中$ Sync.innerSetException(FutureTask.java:273)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:307)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    java.lang.Thread.run(Thread.java:856)
04-23 13:47:29.852:E / AndroidRuntime(2600):产生的原因:
    android.database.sqlite.SQLiteException:没有这样的列:舍入类型(code 1),而
    编译:SELECT * FROM餐厅,名字='RNAME'AND舍入类型=花式
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.database.sqlite.SQLiteConnection.native prepareStatement(本机方法)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.database.sqlite.SQLiteConnection.acquire preparedStatement
    (SQLiteConnection.java:882)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.database.sqlite.SQLiteConnection。prepare(SQLiteConnection.java:493)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.database.sqlite.SQLiteSession。prepare(SQLiteSession.java:588)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.database.sqlite.SQLiteProgram<&初始化GT;(SQLiteProgram.java:58)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.database.sqlite.SQLiteQuery<&初始化GT;(SQLiteQuery.java:37)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.database.sqlite.SQLiteDirectCursorDriver.query
    (SQLiteDirectCursorDriver.java:44)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
   android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
   android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    com.studentapplication.SQLiteCursorLoader.buildCursor(SQLiteCursorLoader.java:88)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    com.studentapplication.AbstractCursorLoader.loadInBackground
    (AbstractCursorLoader.java:24)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    com.studentapplication.AbstractCursorLoader.loadInBackground
    (AbstractCursorLoader.java:1)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:301)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.content.AsyncTaskLoader $ LoadTask.doInBackground(AsyncTaskLoader.java:68)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.content.AsyncTaskLoader $ LoadTask.doInBackground(AsyncTaskLoader.java:56)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    android.os.AsyncTask $ 2.call(AsyncTask.java:287)
04-23 13:47:29.852:E / AndroidRuntime(2600):在
    java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
04-23 13:47:29.852:E / AndroidRuntime(2600):... 4个
04-23 13:47:29.902:W / ActivityManager(161):强制完成活动
    com.studentapplication / .RestaurantSearchResultsActivity
04-23 13:47:29.902:W /窗口管理器(161):未能采取截图为(266x425)到
    层21020


解决方案

在生产,当您修改数据库的模式,你碰到的架构版本号传递给 SQLiteOpenHelper 的构造函数,所以 SQLiteOpenHelper 将调用 onUpgrade()和影响的变化。

在发展,你可以,如果你想做到这一点。但是,很容易忘记这一点。因此,如果你的数据库结构似乎并没有选配的期望,无论是:


  • 凹凸的架构版本号,以强制 onUpgrade()电话,或


  • 消灭现有的数据库,通过在设置你的应用程序的入口等,以武力的onCreate()的调用你的 SQLiteOpenHelper


I am making an android app that searches for restaurants in a SQLite database. I currently use a custom loader (that I found online) to load a cursor from the database and then take that cursor and populate a listview with a SimpleCursorAdapter. I want all the data to be bound but only the name of the restaurant to be displayed (because when I click on a list item I want to get all the data and send it to a new activity that displays the data). If I specify the restaurant name and restaurant type as the search parameters, I run the raw query:

 "SELECT * FROM Restaurant WHERE name = " + name + " AND rType = " + restaurantType; 

in my SQLiteCursorLoader class and I get an error saying that the column rType does not exist, even thought I know the column exists in the Restuarant table. It seems that I get this error when I have two WHERE clauses in my query but this does not happen when I have one WHERE clause. Any help would be GREATLY appreciated! Here is my code:

RestuarantSearchResultsActivity:

package com.studentapplication;
import android.app.Activity;
import android.app.ListActivity;
import android.app.LoaderManager;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class RestaurantSearchResultsActivity extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor>{

DatabaseHelper databaseHelper;
SimpleCursorAdapter mAdapter;
Bundle searchParameters;

@Override
public void onCreate(Bundle savedInstanceState)
{
    Log.w("CoolBeans", "Results Activity Created");
    super.onCreate(savedInstanceState);

    databaseHelper = new DatabaseHelper(getApplicationContext());
    //setContentView(R.layout.restaurant_search_results);

    Bundle searchParameters = getIntent().getExtras();
    String n = searchParameters.getString("name");
    Log.i("0)", n);


    //first N columns should match toViews first N views
    String[] fromColumns = {getString(R.string.database_column_name),
                           getString(R.string.database_column_restaurant_type),
                           getString(R.string.database_column_phone_number),
                           getString(R.string.database_column_address),
               getString(R.string.database_column_csz),
               getString(R.string.database_column_brief_description),
               getString(R.string.database_column_url),
               getString(R.string.database_column_price)};

    int[] toViews = {android.R.id.text1};

    mAdapter = new SimpleCursorAdapter( getApplicationContext(),
                        this.getListView().getId(),
                        null,
                            fromColumns,
                        toViews,
                        0);
    setListAdapter(mAdapter);
    getLoaderManager().initLoader(0, searchParameters, this);       
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle searchParameters) {
    Log.i("3)", "Correct Loader Being Built");
    return new SQLiteCursorLoader(getApplicationContext(),
            databaseHelper,
            searchParameters,
            null);

}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mAdapter.swapCursor(data);

}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    mAdapter.swapCursor(null);

}

@Override
    public void onListItemClick(ListView l, View v, int position, long id)
{
    Cursor myCursor = (Cursor)l.getItemAtPosition(position);
    if(l.isItemChecked(position) == true)
    {
        l.setItemChecked(position, false);
        //shut down previously selected item details

    }
    else
    {
        l.setItemChecked(position, true);

        //start previously selected item details

    }
}


}

SQLiteCursorLoader:

package com.studentapplication;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.os.Bundle;
import android.util.Log;

public class SQLiteCursorLoader extends AbstractCursorLoader
{
SQLiteOpenHelper db=null;
String rawQuery=null;
String[] args=null;

/**
 * Creates a fully-specified SQLiteCursorLoader. See
 * {@link SQLiteDatabase#rawQuery(SQLiteDatabase, String, String[])
 * SQLiteDatabase.rawQuery()} for documentation on the
 * meaning of the parameters. These will be passed as-is
 * to that call.
 */
public SQLiteCursorLoader(Context context, SQLiteOpenHelper db, Bundle
    searchParameters, String[] args)
{
    super(context);
    this.db=db;
    this.rawQuery=createQuery(searchParameters);
    this.args=args;
}

private String createQuery(Bundle searchParameters) {
    String name = "\'";
    name = name + searchParameters.getString("name");
    name = name + "\'";
    int price = searchParameters.getInt("price");
    String restaurantType = "\'";
    restaurantType = restaurantType +
            searchParameters.getString("restaurant_type");
    restaurantType = restaurantType + "\'";

    //String dist = searchParameters.getString("dist");

    String theQuery = "";

    if(!name.equals("\'\'"))
    {
        if(!restaurantType.equals("\'_\'"))
        {
            theQuery = "SELECT * FROM Restaurant WHERE name 
= "+ name + " AND rType = " + restaurantType;
        }
        else if(price != 0)
        {
            theQuery = "SELECT * FROM Restaurant WHERE name = " + name
+ " AND price = " + ((Integer)price).toString();
        }
        else
        {
            theQuery="SELECT * FROM Restaurant WHERE name = " + name;
        }
    }
    else if(!restaurantType.equals("\'\'"))
    {
        theQuery = "SELECT * FROM Restaurant WHERE type = " +
restaurantType + " SORT BY name"; 
    }
    else if(price != 0)
    {
        theQuery="SELECT * FROM Restaurant WHERE price=" + price + " SORT
BY name";
    }



    return theQuery;
}


/**
 * Runs on a worker thread and performs the actual
 * database query to retrieve the Cursor.
 */
@Override
protected Cursor buildCursor()
{
    return(db.getReadableDatabase().rawQuery(rawQuery, args));
}

/**
 * Writes a semi-user-readable roster of contents to
 * supplied output.
 */
@Override
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[]
    args)
{
    super.dump(prefix, fd, writer, args);
    writer.print(prefix);
    writer.print("rawQuery=");
    writer.println(rawQuery);
    writer.print(prefix);
    writer.print("args=");
    writer.println(Arrays.toString(args));
}

public void insert(String table, String nullColumnHack, ContentValues values)
{
    new InsertTask(this).execute(db, table, nullColumnHack, values);
}

public void update(String table, ContentValues values, String whereClause, String[]
    whereArgs)
{
    new UpdateTask(this).execute(db, table, values, whereClause, whereArgs);
}

public void replace(String table, String nullColumnHack, ContentValues values)
{
    new ReplaceTask(this).execute(db, table, nullColumnHack, values);
}

public void delete(String table, String whereClause, String[] whereArgs)
{
    new DeleteTask(this).execute(db, table, whereClause, whereArgs);
}

public void execSQL(String sql, Object[] bindArgs)
{
    new ExecSQLTask(this).execute(db, sql, bindArgs);
}

//Private Classes

private class InsertTask extends ContentChangingTask<Object, Void, Void>
{
    InsertTask(SQLiteCursorLoader loader)
    {
        super(loader);
    }

    @Override
    protected Void doInBackground(Object... params)
    {
        SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
        String table=(String)params[1];
        String nullColumnHack=(String)params[2];
        ContentValues values=(ContentValues)params[3];

        db.getWritableDatabase().insert(table, nullColumnHack, values);

        return(null);
    }
}

private class UpdateTask extends ContentChangingTask<Object, Void, Void>
{
    UpdateTask(SQLiteCursorLoader loader)
    {
        super(loader);
    }

    @Override
    protected Void doInBackground(Object... params)
    {
        SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
        String table=(String)params[1];
        ContentValues values=(ContentValues)params[2];
        String where=(String)params[3];
        String[] whereParams=(String[])params[4];

        db.getWritableDatabase().update(table, values, where, whereParams);

        return(null);
    }
}

private class ReplaceTask extends ContentChangingTask<Object, Void, Void>
{
    ReplaceTask(SQLiteCursorLoader loader)
    {
        super(loader);
    }

    @Override
    protected Void doInBackground(Object... params)
    {
        SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
        String table=(String)params[1];
        String nullColumnHack=(String)params[2];
        ContentValues values=(ContentValues)params[3];

        db.getWritableDatabase().replace(table, nullColumnHack, values);

        return(null);
    }
}

private class DeleteTask extends ContentChangingTask<Object, Void, Void>
{
    DeleteTask(SQLiteCursorLoader loader)
    {
        super(loader);
    }

    @Override
    protected Void doInBackground(Object... params)
    {
        SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
        String table=(String)params[1];
        String where=(String)params[2];
        String[] whereParams=(String[])params[3];

        db.getWritableDatabase().delete(table, where, whereParams);

        return(null);
    }
}

private class ExecSQLTask extends ContentChangingTask<Object, Void, Void>
{
    ExecSQLTask(SQLiteCursorLoader loader)
    {
        super(loader);
    }

    @Override
    protected Void doInBackground(Object... params)
    {
        SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
        String sql=(String)params[1];
        Object[] bindParams=(Object[])params[2];

        db.getWritableDatabase().execSQL(sql, bindParams);

     return(null);
    }
}
}

AbstractCursorLoader:

package com.studentapplication;

import android.annotation.TargetApi;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.database.Cursor;
import android.os.Build;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
abstract public class AbstractCursorLoader extends AsyncTaskLoader<Cursor> {

abstract protected Cursor buildCursor();
Cursor lastCursor=null;

public AbstractCursorLoader(Context context) {
  super(context);
}

/** 
 * Runs on a worker thread, loading in our data. Delegates
 * the real work to concrete subclass' buildCursor() method. 
 */
@Override
public Cursor loadInBackground() {
  Cursor cursor=buildCursor();

  if (cursor!=null) {
    // Ensure the cursor window is filled
    cursor.getCount();
  }

  return(cursor);
}

/**
 * Runs on the UI thread, routing the results from the
 * background thread to whatever is using the Cursor
 * (e.g., a CursorAdapter).
 */
@Override
public void deliverResult(Cursor cursor) {
  if (isReset()) {
    // An async query came in while the loader is stopped
    if (cursor!=null) {
      cursor.close();
    }

    return;
  }

  Cursor oldCursor=lastCursor;
  lastCursor=cursor;

  if (isStarted()) {
    super.deliverResult(cursor);
  }

  if (oldCursor!=null && oldCursor!=cursor && !oldCursor.isClosed()) {
    oldCursor.close();
  }
}

/**
 * Starts an asynchronous load of the list data.
 * When the result is ready the callbacks will be called
 * on the UI thread. If a previous load has been completed
 * and is still valid the result may be passed to the
 * callbacks immediately.
 * 
 * Must be called from the UI thread.
 */
@Override
protected void onStartLoading() {
  if (lastCursor!=null) {
    deliverResult(lastCursor);
  }

  if (takeContentChanged() || lastCursor==null) {
    forceLoad();
  }
}

/**
* Must be called from the UI thread, triggered by a
* call to stopLoading().
*/
@Override
protected void onStopLoading() {
  // Attempt to cancel the current load task if possible.
  cancelLoad();
}

/**
 * Must be called from the UI thread, triggered by a
 * call to cancel(). Here, we make sure our Cursor
 * is closed, if it still exists and is not already closed.
 */
@Override
public void onCanceled(Cursor cursor) {
  if (cursor!=null && !cursor.isClosed()) {
    cursor.close();
  }
}

/**
 * Must be called from the UI thread, triggered by a
 * call to reset(). Here, we make sure our Cursor
 * is closed, if it still exists and is not already closed.
 */
@Override
protected void onReset() {
  super.onReset();

  // Ensure the loader is stopped
  onStopLoading();

  if (lastCursor!=null && !lastCursor.isClosed()) {
    lastCursor.close();
  }

  lastCursor=null;
  }
  }

DatabaseHelper:

package com.studentapplication;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {

// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;

// Database Name
private static final String DATABASE_NAME = "LOCAL_DATABASE";

// table Names
private static final String TABLE_Restaurant = "Restaurant";
private static final String TABLE_Coupon = "Coupon";
private static final String TABLE_Linker = "Linker";

//restaurant columns
private static final String R_Name = "name";
private static final String R_Description = "description";
private static final String R_Address = "address";
private static final String R_CSZ = "CSZ";
private static final String R_URL = "url";
private static final String R_Price = "price";
private static final String R_Type = "rType";
private static final String R_ID = "_id";

//coupon columns
private static final String C_ID = "_id";
private static final String C_NAME = "name";
private static final String C_Description = "description";

//linker table columns
private static final String r_id = "r_id";
private static final String c_id = "c_id";
private static final String date = "date";
private static final String l_id = "l_id";

public DatabaseHelper(Context context)
{
    super(context, DATABASE_NAME, null, DATABASE_VERSION);

}

public DatabaseHelper(Context context, String name, CursorFactory factory,
        int version) {
    super(context, name, factory, version);
}

// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_Restaurant_TABLE = "CREATE TABLE " + TABLE_Restaurant + "( "
            + R_ID + " INTEGER PRIMARY KEY, "
            + R_Name + " TEXT NOT NULL, " 
            + R_Type + " TEXT NOT NULL, "
            + R_Address + " TEXT NOT NULL, " 
            + R_CSZ + " TEXT NOT NULL, "
            + R_Description + " TEXT NOT NULL, " 
            + R_URL + " TEXT NOT NULL, "
            + R_Price +" INTEGER NOT NULL"
            + " )";

    String CREATE_Coupon_TABLE = "CREATE TABLE " + TABLE_Coupon + "("
            + C_ID + " INTEGER PRIMARY KEY, " 
            + C_NAME + " TEXT, "
            + C_Description + " TEXT"
            + ")";

    String CREATE_Linker_TABLE = "CREATE TABLE " + TABLE_Linker + "("
            + r_id + " INTEGER, " 
            + c_id + " INTEGER, " 
            + date + " DATE, "
            + l_id + "INTEGER PRIMARY KEY, "
            + "FOREIGN KEY(r_id) REFERENCES Restaurant(_id), "
            + "FOREIGN KEY(c_id) REFERENCES Coupon(_id) )";

    db.execSQL(CREATE_Restaurant_TABLE);
    db.execSQL(CREATE_Coupon_TABLE);
    db.execSQL(CREATE_Linker_TABLE);
}

// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // Drop older table if existed
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_Restaurant);
    // Create tables again
    onCreate(db);
}

}

Stack Trace:

04-23 13:47:29.691: E/SQLiteLog(2600): (1) no such column: rType
04-23 13:47:29.691: W/dalvikvm(2600): threadid=11: thread exiting with uncaught
    exception (group=0x40a13300)
04-23 13:47:29.852: E/AndroidRuntime(2600): FATAL EXCEPTION: AsyncTask #1
04-23 13:47:29.852: E/AndroidRuntime(2600): java.lang.RuntimeException: An error
    occured while executing doInBackground()
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.os.AsyncTask$3.done(AsyncTask.java:299)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    java.lang.Thread.run(Thread.java:856)
04-23 13:47:29.852: E/AndroidRuntime(2600): Caused by:
    android.database.sqlite.SQLiteException: no such column: rType (code 1): , while
    compiling: SELECT * FROM Restaurant WHERE name = 'RName' AND rType = 'Fancy'
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.database.sqlite.SQLiteConnection.acquirePreparedStatement
    (SQLiteConnection.java:882)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.database.sqlite.SQLiteDirectCursorDriver.query
    (SQLiteDirectCursorDriver.java:44)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
   android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
   android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    com.studentapplication.SQLiteCursorLoader.buildCursor(SQLiteCursorLoader.java:88)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    com.studentapplication.AbstractCursorLoader.loadInBackground
    (AbstractCursorLoader.java:24)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    com.studentapplication.AbstractCursorLoader.loadInBackground
    (AbstractCursorLoader.java:1)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:301)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:68)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:56)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    android.os.AsyncTask$2.call(AsyncTask.java:287)
04-23 13:47:29.852: E/AndroidRuntime(2600):     at
    java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-23 13:47:29.852: E/AndroidRuntime(2600):     ... 4 more
04-23 13:47:29.902: W/ActivityManager(161):   Force finishing activity
    com.studentapplication/.RestaurantSearchResultsActivity
04-23 13:47:29.902: W/WindowManager(161): Failure taking screenshot for (266x425) to
    layer 21020

解决方案

In production, when you modify the schema of your database, you bump the schema version number you pass to the SQLiteOpenHelper constructor, so SQLiteOpenHelper will call onUpgrade() and affect the change.

In development, you can do that too if you wish. But, it's easy to forget that. Hence, if your database structure does not seem to be matching expectations, either:

  • Bump that schema version number, to force an onUpgrade() call, or

  • Wipe out the existing database, via an uninstall, "Clear Data" from your app's entry in Settings, etc., to force a call to onCreate() of your SQLiteOpenHelper

这篇关于Android的SQLite的列未找到错误当执行原始查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆