2013-04-11 59 views
5

我執行下面的方法沒有成功的東陽的selectArgs是不正確的(至少這是我相信Android中選擇NULL值的SQLite

的findAll:

public Collection<Object> findAllByCodigoSetorOrderByStatusWhereDataAgendamentoIsNull(Integer vendedor) { 
    Collection<Object> objects = null; 
    String selection = Object.FIELDS[20] + "=?" + " OR " + Object.FIELDS[20] + "=?" + " OR " + Object.FIELDS[20] + "=?" + " AND " + Object.FIELDS[6] + "=?"; 
    String[] selectionArgs = new String[] { "''", "'null'", "NULL", String.valueOf(vendedor) }; 
    Collection<ContentValues> results = findAllObjects(Object.TABLE_NAME, selection, selectionArgs, Object.FIELDS, null, null, Object.FIELDS[4]); 
    objects = new ArrayList<Object>(); 
    for (ContentValues result : results) { 
     objects.add(new Object(result)); 
    } 
    return objects; 
} 

findAllObjects:

protected Collection<ContentValues> findAllObjects(String table, String selection, String[] selectionArgs, String[] columns, String groupBy, String having, String orderBy) { 
     Cursor cursor = null; 
     ContentValues contentValue = null; 
     Collection<ContentValues> contentValues = null; 
     try { 
      db = openRead(this.helper); 
      if (db != null) { 
       cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy); 
       contentValues = new ArrayList<ContentValues>(); 
       for (int i = 0; i < cursor.getCount(); i++) { 
        cursor.moveToPosition(i); 
        contentValue = new ContentValues(); 
        for (int c = 0; c < cursor.getColumnCount(); c++) { 
         contentValue.put(cursor.getColumnName(c), cursor.getString(c)); 
        } 
        contentValues.add(contentValue); 
        cursor.moveToNext(); 
       } 
      } 
      return contentValues; 
     } finally { 
      close(db); 
     } 
    } 

我怎樣才能正確地選擇和列比較 - NUL l,'null'和''使用db.query?

+0

你用'Cursor'處理你的數據? – Cornholio 2013-04-11 15:51:54

+1

編輯使問題更清晰......感謝Cornholio的問題。 – MBarni 2013-04-11 15:53:24

+0

最簡單的方法來檢查行的空值是這樣的 - 'if(cursor.isNull(cursor.getColumnIndex(「my_column」))doStuff();'。有什麼理由你不能使用它? – Cornholio 2013-04-11 15:55:10

回答

11

Android的數據庫API不允許傳遞NULL值作爲參數;它只允許字符串。 (這是一個可怕的設計錯誤。更糟的是,SQLiteStatement確實允許所有類型的參數,但只適用於返回單個值的查詢。)

你沒有選擇,只能查詢字符串更改爲blah IS NULL

+0

這應該(我希望已經是)在Android列表中標記爲錯誤/請求。 – MBarni 2013-04-11 17:44:23

+0

'是null'的必要性是傳統的SQL語法。 '= null'不返回_any_ SQL數據庫管理系統中的結果。而且爲它使用一個參數也沒有意義。首先,因爲語法是不同的,其次,因爲總是使用相同的字符串。在你的情況下,我會使用參數替換*僅用於變量vendedor *。對於那些其他的固定值,這根本就不需要,因此浪費CPU週期和電池壽命(即使只是稍微)。只有當參數可以包含變量值時,它們纔有用。 – 2013-04-12 14:26:48

+1

@CL。事實上,SQLiteStatement是一個糟糕的類。邊界無用。 – 2013-04-12 14:30:47

0

老問題,但我仍然堅持了幾個小時,直到我找到了這個答案。無論出於何種原因,這種奇怪的行爲(或錯誤)在Android SDK中仍然存在,如果你想查詢使用的空值根本就

SQLiteDatabase db = getReadableDatabase(); 
ContentValues contentValues = new ContentValues(); 

contentValues.put("columnName", newValue); 

String nullSelection = "columnName" + " IS NULL"; 

db.update("tableName", contentValues, nullSelection, null); 
db.close(); 

在這個例子中,我更新的價值觀,但它是一個類似的概念時,只是選擇值

0

正如其他答案中所提到的,對於空值「IS NULL」需要使用。下面是兼具空字符串和一些方便的代碼(我用的例子刪除,但同樣可以用於其他的方法來完成,例如查詢):

public void deleteSomething(String param1, String param2, String param3) { 
    ArrayList<String> queryParams = new ArrayList<>(); 

    mDb.delete(TABLE_NAME, 
      COLUMN_A + getNullSafeComparison(param1, queryParams) + "AND " + 
        COLUMN_B + getNullSafeComparison(param2, queryParams) + "AND " + 
        COLUMN_C + getNullSafeComparison(param3, queryParams), 
      queryParams.toArray(new String[0])); 
} 

private String getNullSafeComparison(String param, List<String> queryParams) { 
    if (param == null) { 
     return " IS NULL "; 
    } else { 
     queryParams.add(param); 
     return " = ? "; 
    } 
}