title: Android SQLite Column Not Found Error When Executing Raw Query
body: <p>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:</p>
  
  <pre><code> "SELECT * FROM Restaurant WHERE name = " + name + " AND rType = " + restaurantType; 
  </code></pre>
  
  <p>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:</p>
  
  <p>RestuarantSearchResultsActivity:</p>
  
  <pre><code>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&lt;Cursor&gt;{
  
  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&lt;Cursor&gt; onCreateLoader(int id, Bundle searchParameters) {
      Log.i("3)", "Correct Loader Being Built");
      return new SQLiteCursorLoader(getApplicationContext(),
              databaseHelper,
              searchParameters,
              null);
  
  }
  
  @Override
  public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) {
      mAdapter.swapCursor(data);
  
  }
  
  @Override
  public void onLoaderReset(Loader&lt;Cursor&gt; 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
  
      }
  }
  
  
  }
  </code></pre>
  
  <p>SQLiteCursorLoader:</p>
  
  <pre><code>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&lt;Object, Void, Void&gt;
  {
      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&lt;Object, Void, Void&gt;
  {
      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&lt;Object, Void, Void&gt;
  {
      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&lt;Object, Void, Void&gt;
  {
      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&lt;Object, Void, Void&gt;
  {
      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);
      }
  }
  }
  </code></pre>
  
  <p>AbstractCursorLoader:</p>
  
  <pre><code>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&lt;Cursor&gt; {
  
  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 &amp;&amp; oldCursor!=cursor &amp;&amp; !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 &amp;&amp; !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 &amp;&amp; !lastCursor.isClosed()) {
      lastCursor.close();
    }
  
    lastCursor=null;
    }
    }
  </code></pre>
  
  <p>DatabaseHelper:</p>
  
  <pre><code>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);
  }
  
  }
  </code></pre>
  
  <p>Stack Trace:</p>
  
  <pre><code>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.&lt;init&gt;(SQLiteProgram.java:58)
  04-23 13:47:29.852: E/AndroidRuntime(2600):     at
      android.database.sqlite.SQLiteQuery.&lt;init&gt;(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
  </code></pre>