任何东西都可以在下面更改以达到工作解决方案!我完全控制了下面所有的模式/数据/查询/代码,所以任何合理的改进都是受欢迎的:我正在寻找一个简单/干净/到点的解决方案。例如,进行两个不同的查询(__、= ?和is null__)是的最后手段__。
问题
我想修改下面的代码,这样我就可以调用listCategoriesIn(1)和listCategoriesIn(null),它们都给出了正确的预期结果。我不能让listCategoriesIn(null)使用像c.parent = ?这样的WHERE子句。
INTEGER或NULL绑定到= ?WHERE子句,使其在这两种情况下都能工作?表格
CREATE TABLE Category (
_id INTEGER NOT NULL,
name VARCHAR NOT NULL,
parent INTEGER NULL --< important bit
CONSTRAINT fk_Category_parent
REFERENCES Category(_id)
ON UPDATE CASCADE
ON DELETE CASCADE,
PRIMARY KEY(_id AUTOINCREMENT),
UNIQUE(name)
);样本数据
INSERT INTO Category
(_id, parent, name)
SELECT 0, NULL, 'cat0' --< expected for listCategoriesIn(null)
UNION SELECT 1, NULL, 'cat1' --< expected for listCategoriesIn(null)
UNION SELECT 11, 1, 'cat1-1' --< expected for listCategoriesIn(1)
UNION SELECT 12, 1, 'cat1-2' --< expected for listCategoriesIn(1)
UNION SELECT 121, 12, 'cat1-2-1'
UNION SELECT 122, 12, 'cat1-2-2'
UNION SELECT 13, 1, 'cat1-3' --< expected for listCategoriesIn(1)
UNION SELECT 131, 13, 'cat1-3-1'
UNION SELECT 2, NULL, 'cat2' --< expected for listCategoriesIn(null)
UNION SELECT 21, 2, 'cat2-1'
UNION SELECT 3, NULL, 'cat3' --< expected for listCategoriesIn(null)
;查询
IRL I使用更复杂的方法,包括视图、子查询和多个联接。
select
c.*,
(select count() from Category where parent = c._id) as count
from Category c
where c.parent = ? --< important bit
;错误代码#1
public Cursor listCategoriesIn(SQLiteDatabase db, Long categoryID) {
// public Cursor SQLiteDatabse.rawQuery(String sql, String[] selectionArgs);
return db.rawQuery(CATEGORY_QUERY, new String[] {
String.valueOf(categoryID)
});
}
listCategoriesIn(1):工作正常listCategoriesIn(null):生成的游标为空,可能是= 'null'或= NULL绑定的。
错误代码#2
public Cursor listCategoriesIn(SQLiteDatabase db, Long categoryID) {
// public Cursor SQLiteDatabse.rawQuery(String sql, String[] selectionArgs);
return db.rawQuery(CATEGORY_QUERY, new String[] {
categoryID == null? null : categoryID.toString()
});
}
listCategoriesIn(1):工作正常listCategoriesIn(null):java.lang.IllegalArgumentException:索引1处的绑定值为null
发布于 2015-03-11 17:39:11
睡了一觉,开始了新的一天,我顿悟了,没有重复的查询是可能的:
where c.parent = ? or (? = 'null' and c.parent is null)但是,我们需要复制这个参数,下面是相应的Java调用:
public Cursor listCategoriesIn(SQLiteDatabase db, Long categoryID) {
return db.rawQuery(CATEGORY_QUERY, new String[] {
String.valueOf(categoryID), String.valueOf(categoryID)
});
}当categoryID是null时,不存在NPE,因为它绑定为"null" (参见valueOf)。将null->'null'传递给驱动程序将激活WHERE子句的第二部分,当然没有一个INTEGER值是= 'null',因此第一部分不起作用。
这个技巧之所以奏效,是因为S和SQLite引擎可以处理将INTEGER与TEXT中的数字进行比较。我确信细节可以在SQLite数据类型文档中找到。
发布于 2015-03-10 21:16:29
我认为当字段为NULL时,需要发送不同的SQL语句。
public Cursor listCategoriesIn(SQLiteDatabase db, Long categoryID) {
if(categoryID == null)
return db.rawQuery(CATEGORY_QUERY_NULL, null);
else
return db.rawQuery(CATEGORY_QUERY, new String[] { categoryID.toString() });
}其中CATEGORY_QUERY_NULL是与CATEGORY_QUERY相同的查询,但是使用c.parent IS NULL而不是c.parent = ?。有关详细信息,请参阅此回答。
https://stackoverflow.com/questions/28973491
复制相似问题