2012-11-12 95 views
4

最近,我已經因爲代碼的一些錯誤是這樣的:我可以讓SQLiteDatabase抱怨缺少參數嗎?

Cursor myCursor = myDb.rawQuery(
     "SELECT ... " + 
     " FROM ...complicated join... " + 
     " WHERE field1 = ? AND (field2 = ? OR field3 = ?) ", 
     new String[] {myField1, myField2}); // Oops, forgot about field3 

發生這種情況時,查詢只是默默地忽略缺少的參數,導致錯誤被忽視。有一些pedantic設置或其他什麼東西,我可以用來使SQLite尖叫(在運行時)佔位符的數量和字段數量不匹配?

我知道我可以建立自己的包裝,但我不知道是否有內置的東西...

+1

線的東西有沒有,你必須使用原始查詢,原因是什麼?我的意思是如果你使用查詢,你可以斷言column [] .length == values [] .length。 – Simon

+0

@Simon:不一定。我可能會選擇列A和B(='列'),但在列C,D和E(='selectionArgs')上進行過濾。 – Heinzi

回答

1

的Android基本上是剛好路過ARGS未檢查到本機的SQLite,看到http://www.sqlite.org/c3ref/bind_blob.html

如果某些東西沒有被綁定,它就被認爲是綁定到NULL。綁定了太多應該導致一個錯誤,雖然

我不知道/沒有看到Android的源那種檢查任何調試選項,但你也許可以編寫一些代碼來檢查您的SQL語法:

SQLiteChecker mDbChecked = new SQLiteChecker(mDb); 
Cursor c = mDbChecked.rawQuery("select complicated from table where stuff=?", 
     new String[] {"one", "two"}); 

其中SQLiteChecker將沿

/** 
* Simple Delegate for SQLiteDatabase 
*/ 
public class SQLiteChecker { 
    private final SQLiteDatabase mDbDelegate; 
    public SQLiteChecker(SQLiteDatabase db) { 
     mDbDelegate = db; 
    } 
    // ------------ Delegate methods --------------------// 
    public int delete(String table, String whereClause, String[] whereArgs) { 
     checkSQL(whereClause, whereArgs); 
     return mDbDelegate.delete(table, whereClause, whereArgs); 
    } 

    public int update(String table, ContentValues values, String whereClause, String[] whereArgs) { 
     checkSQL(whereClause, whereArgs); 
     return mDbDelegate.update(table, values, whereClause, whereArgs); 
    } 

    public void execSQL(String sql, Object[] bindArgs) throws SQLException { 
     checkSQL(sql, bindArgs); 
     mDbDelegate.execSQL(sql, bindArgs); 
    } 

    public Cursor rawQuery(String sql, String[] selectionArgs) { 
     checkSQL(sql, selectionArgs); 
     return mDbDelegate.rawQuery(sql, selectionArgs); 
    } 

    // add more if you need 

    // -------------- checking logic -------------------// 
    private static void checkSQL(String query, Object[] args) { 
     // bit unreliable but simple: 
     // just check if amount of ? matches args.length 
     int expected = countChar(query, '?'); 
     int actual = args != null ? args.length : 0; 
     if (expected != actual) { 
      Log.e("CHECK", "You seem to have messed up [" + query + "]"); 
      Log.e("CHECK", "expected:" + expected + " actual:" + actual); 
     } 
    } 

    private static int countChar(String string, char ch) { 
     if (string == null) return 0; 
     int count = 0; 
     for (int i = 0; i < string.length(); i++) { 
      if (string.charAt(i) == ch) 
       count++; 
     } 
     return count; 
    } 
} 
相關問題