2014-11-06 217 views
-3

我遇到查詢語法的問題。我在MainActivity中有一個列表視圖,並將位置傳遞給第二個活動,然後運行查詢。我也有一個數據模型類,Promise和一個適配器類,當然還有Database Handler類。下面是在MainActivity:SQLite數據庫查詢的查詢語法錯誤

public class MainActivity extends Activity { 

ListView listView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    listView = (ListView) findViewById(R.id.listViewCategories); 
    String[] categories = getResources().getStringArray(R.array.categories_array); 

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
      android.R.layout.simple_list_item_1, categories); 

    listView.setAdapter(adapter); 
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      // ListView Clicked item index 
      int itemPosition = position; 
      // ListView Clicked item value 
      String itemValue = (String) listView.getItemAtPosition(position); 
      // Show Alert 
      Toast.makeText(getApplicationContext(), 
        "Position: " + itemPosition + " List Item: " + itemValue, 
        Toast.LENGTH_LONG) 
        .show(); 
      Intent i = new Intent(MainActivity.this, DisplayResult.class); 
      Bundle bundle = new Bundle(); 
      bundle.putString("itemValue", itemValue); 
      i.putExtras(bundle); 
      startActivity(i); 
     } 


    }); 
} 

}

下面是有它的查詢DisplayResult類:

public class DisplayResult extends ListActivity { 

private ArrayList<String> results = new ArrayList<String>(); 
private SQLiteDatabase database; 
private String selectedCategory; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.verses); 

    Bundle b = getIntent().getExtras(); 
    String selectedCategory = b.getString("itemValue"); 

    // construct the data source 
    ArrayList<Promise> verses = new ArrayList<Promise>(); 
    // create the adapter to convert the array to views 
    // PromiseAdapter adapter = new PromiseAdapter(this, verses); 
    // attach the adapter to a listview 
    // ListView listView = (ListView) findViewById(R.id.listViewItems); 
    // listView.setAdapter(adapter); 
    setListAdapter(new ArrayAdapter<String>(this, 
      android.R.layout.simple_list_item_1, results)); 
    getListView().setTextFilterEnabled(true); 

    openAndQueryDatabase(); 
} // end onCreate 

private void openAndQueryDatabase() { 
    SQLiteDatabase newDB = null; 
    try { 
     MyDBHandler dbHandler = new MyDBHandler(this.getApplicationContext()); 
     newDB = dbHandler.getReadableDatabase(); 
     Cursor c = newDB.query("SELECT * FROM " + MyDBHandler.TABLE_NAME + " WHERE KEY_CATEGORY = " + selectedCategory); 

     if (c != null) { 
      if (c.moveToFirst()) { 
       do { 
        String category = c.getString(c.getColumnIndex("KEY_CATEGORY")); 
        String book = c.getString(c.getColumnIndex("KEY_BOOK")); 
        String chapter = c.getString(c.getColumnIndex("KEY_CHAPTER")); 
        String verse = c.getString(c.getColumnIndex("KEY_VERSE")); 
        String word = c.getString(c.getColumnIndex("KEY_WORD")); 
        results.add(category + book + chapter + verse + word); 
       } while (c.moveToNext()); 
      } // end inner if 
     } // end outer if 
    } catch (SQLiteException se) { 
     Log.e(getClass().getSimpleName(), "Could not create or open the database"); 
    } finally { 
     if (newDB != null) { 
      newDB.execSQL("DELETE FROM " + MyDBHandler.TABLE_NAME); 
     } 
      newDB.close(); 
    } 

這裏的適配器類:

public class PromiseAdapter extends ArrayAdapter<Promise> { 

public PromiseAdapter(Context context, ArrayList<Promise> verses) { 
    super(context, 0, verses); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // get the data item for this position 
    Promise promise = getItem(position); 
    // check to see if an existing view is being reuses, otherwise inflate the view 
    if (convertView == null) { 
     convertView = LayoutInflater.from(getContext()).inflate(R.layout.verses, parent, false); 
    } 
    // lookup view for data population 
    TextView txtCategory = (TextView) convertView.findViewById(R.id.txtViewCategory); 
    TextView txtBook = (TextView) convertView.findViewById(R.id.txtViewBook); 
    TextView txtChapter = (TextView)convertView.findViewById(R.id.txtViewChapter); 
    TextView txtVerse = (TextView) convertView.findViewById(R.id.txtViewVerse); 
    TextView txtWord = (TextView) convertView.findViewById(R.id.txtViewWord); 
    // populate the data into the template view using the data object 
    txtCategory.setText(promise._category); 
    txtBook.setText(promise._book); 
    txtChapter.setText(promise._chapter); 
    txtVerse.setText(promise._verse); 
    txtWord.setText(promise._word); 
    // return the completed view to render on screen 
    return convertView; 
} 

這裏的數據庫處理程序(或助手)等級:

public class MyDBHandler extends SQLiteOpenHelper { 

private static String DATABASE_PATH = 
    "/data/data/com.blogspot.joyouslybeingjoy.biblecyb/databases/"; 
private static final String DATABASE_NAME = "promisesdatabase.sqlite"; 
private static final int DATABASE_VERSION = 1; 
public static final String TABLE_NAME = "promises"; 
public static final String KEY_ROWID = "_id"; 
public static final String KEY_CATEGORY = "category"; 
public static final String KEY_BOOK = "book"; 
public static final String KEY_CHAPTER = "chapter"; 
public static final String KEY_VERSE = "verse"; 
public static final String KEY_WORD = "word"; 

private static final String DATABASE_CREATE = 
     "CREATE TABLE if not exists " + TABLE_NAME + " (" + 
       KEY_ROWID + "integer PRIMARY KEY," + 
       KEY_CATEGORY + " TEXT," + 
       KEY_BOOK + " TEXT," + 
       KEY_CHAPTER + " TEXT," + 
       KEY_VERSE + " TEXT," + 
       KEY_WORD + " TEXT" + ")"; 

/** 
* Constructor 
* Takes and keeps a reference of the passed context in order to access to the 
* application assets and resources. 
*/ 
public MyDBHandler(Context context) { 
    super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    this.myContext = context; 
    //createDatabase(); 
} 

private SQLiteDatabase myDataBase; 
private final Context myContext; 

public void createDataBase() throws IOException { 
    boolean dbExist = checkDataBase(); 
    if (dbExist) { 
     //do nothing - database already exist 
    } else { 
     //By calling this method and empty database will be created into the default system 

     //of your application so we are gonna be able to overwrite that database with our 
     this.getReadableDatabase(); 

     try { 
      copyDataBase(); 
     } catch (IOException e) { 
      throw new Error("Error copying database"); 
     } 
    } 
} 
/** 

* 
* @return true if it exists, false if it doesn't 
*/ 
private boolean checkDataBase() { 
    SQLiteDatabase checkDB = null; 
    try { 
     String myPath = DATABASE_PATH + DATABASE_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
    } catch (SQLiteException e) { 
     //database doesn't exist yet. 
    } 
    if (checkDB != null) { 
     checkDB.close(); 
    } 
    return checkDB != null ? true : false; 
} 
/** 
* Copies your database from your local assets-folder to the just created empty database in 
* system folder, from where it can be accessed and handled. 
* This is done by transferring bytestream. 
*/ 
private void copyDataBase() throws IOException { 
    //Open your local db as the input stream 
    InputStream myInput = myContext.getAssets().open(DATABASE_NAME); 
    // Path to the just created empty db 
    String outFileName = DATABASE_PATH + DATABASE_NAME; 
    //Open the empty db as the output stream 
    OutputStream myOutput = new FileOutputStream(outFileName); 
    //transfer bytes from the inputfile to the outputfile 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = myInput.read(buffer)) > 0) { 
     myOutput.write(buffer, 0, length); 
    } 
    //Close the streams 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 
} 
public void openDataBase() throws SQLException { 
    //Open the database 
    String myPath = DATABASE_PATH + DATABASE_NAME; 
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
} 
@Override 
public synchronized void close() { 
    if (myDataBase != null) 
     myDataBase.close(); 
    super.close(); 
} 
public void onCreate(SQLiteDatabase db) { 
    //Log.w(LOG_TAG, DATABASE_CREATE); 
    db.execSQL(DATABASE_CREATE); 
} 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    //Log.w(LOG_TAG, "Upgrading database from " + oldVersion + " to " + newVersion 
    // + ", which will destroy all old data (user pref, features"); 
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
    onCreate(db); 
} 

最後的數據模型(或對象)類:

public class Promise { 
//private variables 
int _id; 
String _category; 
String _book; 
String _chapter; 
String _verse; 
String _word; 

// empty constructor 
public Promise() { 
} 
// constructor (input) 
public Promise(int rowid, String category, String book, String chapter, String verse, 
       String word) { 
    this._id = rowid; 
    this._category = category; 
    this._book = book; 
    this._chapter = chapter; 
    this._verse = verse; 
    this._word = word; 
} 
// constructor (output) 
public Promise(String category, String book, String chapter, String verse, String word) { 
    this._category = category; 
    this._book = book; 
    this._chapter = chapter; 
    this._verse = verse; 
    this._word = word; 
} 
// getters and setters 
public int getRowID() { return this._id; } 
public void setRowID(int rowID) { this._id = rowID; } 

public String getCategory() { 
    return this._category; 
} 
public void setCategory(String category) { 
    this._category = category; 
} 

public String getBook() { 
    return this._book; 
} 
public void setBook(String book) { 
    this._book = book; 
} 

public String getChapter() { 
    return this._chapter; 
} 
public void setChapter(String chapter) { 
    this._chapter = chapter; 
} 

public String getVerse() { 
    return this._verse; 
} 
public void setVerse(String verse) { 
    this._verse = verse; 
} 

public String getWord() { 
    return this._word; 
} 
public void setWord(String word) { 
    this._word = word; 
} 

/* (non-Javadoc) 
    * @see java.lang.Object#toString() 
    */ 
// will be used by the ArrayAdapter in the ListView 
@Override 
public String toString() { 
    return "Promise [category=" + _category + ", book=" + _book + ", chapter=" + _chapter 
      + ", verse=" + _verse + ", word=" + _word + "]"; 
} 

任何及所有幫助是極大的讚賞! 謝謝!

回答

1
Cursor c = newDB.query("SELECT * FROM " + MyDBHandler.TABLE_NAME + " WHERE KEY_CATEGORY = " + selectedCategory); 

使用rawQuery()像這樣裸露的SQL查詢。

如果selectedCategory是一個字符串,則將其放入'single quotes'或更好,?參數中。

例如:

Cursor c = newDB.rawQuery("SELECT * FROM " + MyDBHandler.TABLE_NAME + " WHERE KEY_CATEGORY = ?", new String[] { selectedCategory }); 
+0

那麼,錯誤標誌走了,但我的應用程序沒有運行。當我點擊MainActivity的ListView中的一個項目時,它停止工作。不知道發生了什麼。 – 999 2014-11-06 21:03:58

+0

從堆棧跟蹤開始。 http://stackoverflow.com/questions/23353173/uncomfort-myapp-has-stopped-how-can-i-solve-this – laalto 2014-11-06 21:05:13

+0

我不能得到任何東西在Logcat上出來!是的,我沒有說我昨天甚至找不到它。今天上傳了新的Android Studio。發現它,但沒有任何印刷! – 999 2014-11-07 18:23:58